/// <summary> /// 优先从Redis或内存中读取 /// </summary> /// <param name="userName"></param> /// <param name="rank"></param> /// <param name="parentId"></param> /// <returns></returns> public static List <ResourceMenuInfo> getResourceMenuFormRedisOrMemory(String userName, int rank, String parentId) { //暂时先全部执行数据库 //return getResourceMenu(userName, rank, parentId); RedisModel redisModel = getResourceMenuOnlyFormRedisOrMemory(userName); //Log4netHelper.WriteErrorLogByLog4Net(typeof(JwtHelp), "查询内存数据:" + JsonConvert.SerializeObject(redisModel)); List <ResourceMenuInfo> menus = new List <ResourceMenuInfo>(); if (redisModel == null) {//说明redis或内存中没有 menus = getResourceMenu(userName, rank, parentId); setResourceMenuToRedisOrMemory(userName, menus); redisModel = new RedisModel() { resourceMenuInfoList = menus, updateTime = WIPCommon.ForamtCurDateTime(), userName = userName }; //Log4netHelper.WriteInfoLogByLog4Net(typeof(JwtHelp), "redisModel:" + JsonConvert.SerializeObject(redisModel)); } if (redisModel == null) { return(null); } return(redisModel.resourceMenuInfoList); //*/ }
/// <summary> /// 生成Token /// </summary> /// <param name="userName">登录用户名</param> /// <param name="tokenInfos"></param> /// <param name="expDays">有效天数</param> /// <returns></returns> public static string GenerateToken(String userName, List <TokenInfo> tokenInfos, int expDays = 30) { var credentials = new SigningCredentials (securityKey, SecurityAlgorithms.HmacSha384); var header = new JwtHeader(credentials); var payload = new JwtPayload(); var now = WIPCommon.GetUnixTimeStampWithGLWZForSeconds().ToString(); // 30天过期 var exp = long.Parse(now) + (expDays * 24 * 60 * 60);//单位:秒 //注释下面的代码 [EditBy shaocx,2019-01-07] /* * if (userName.Contains("integrated")) * { * exp = long.Parse(now) + 31536000; * } * //*/ payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, now)); //发布时间 payload.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, exp.ToString())); //到期时间 payload.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, WIP)); //发行人 payload.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, userName)); //主题 // 追加自定义字段 数据库字段 payload.AddClaim(new Claim("username", userName)); //自定义对象之用户名称 // 自动获取payload if (tokenInfos != null) { payload.Add("usergroup", tokenInfos);//自定义对象之用户角色集合 } else { payload.Add("usergroup", getTokenInfos(userName));//自定义对象之用户角色集合 } var secToken = new JwtSecurityToken(header, payload); var handler = new JwtSecurityTokenHandler(); String tokenString = handler.WriteToken(secToken); return(tokenString); }
/// <summary> /// 权限写入Redis或内存 /// </summary> /// <param name="menus"></param> private static void setResourceMenuToRedisOrMemory(string userName, List <ResourceMenuInfo> menus) { RedisModel redisModel = new RedisModel() { userName = userName, resourceMenuInfoList = menus, updateTime = WIPCommon.ForamtCurDateTime() }; if (AuthType == WipAuthType.REDIS) { } else { //写入缓存中 wipAuthCacheDict.TryAdd(userName, redisModel); //尝试新增 wipAuthCacheDict[userName] = redisModel; //更新 } }
/// <summary> /// 验证Token /// </summary> /// <param name="token">token值</param> /// <param name="requestURL">请求URL</param> /// <param name="msg">验证信息</param> /// <param name="userInfos">验证完毕的Token对象集合</param> /// <returns></returns> public static bool verifyToken(String token, String requestURL, out String msg, out List <TokenInfo> userInfos) { SecurityToken secToken = new JwtSecurityToken(); var handler = new JwtSecurityTokenHandler(); TokenValidationParameters par = new TokenValidationParameters { RequireExpirationTime = true, RequireSignedTokens = true, ValidateActor = false, ValidateAudience = false, //true, ValidateIssuer = true, ValidateIssuerSigningKey = true, //false, ValidateTokenReplay = false, ValidIssuer = WIP, IssuerSigningKey = securityKey, }; try { handler.ValidateToken(token, par, out secToken); JwtSecurityToken jwtToken = handler.ReadJwtToken(token); // 确认过期 long now = WIPCommon.GetUnixTimeStampWithGLWZForSeconds(); // 条件为!(iat < now && now < exp) >>令牌过期 // 如果是集成用户,则不需要校验令牌是否过期 if ((jwtToken.Payload.Iat <= now && now <= jwtToken.Payload.Exp) || jwtToken.Payload.Sub.ToUpper().IndexOf("integrated".ToUpper()) > -1) { // 确认roles变更 JavaScriptSerializer serializer = new JavaScriptSerializer(); List <ResourceMenuInfo> userRoles = getResourceMenuFormRedisOrMemory(jwtToken.Payload.Sub, 0, ""); List <TokenInfo> payloadRoles = new List <TokenInfo>(); foreach (Claim c in jwtToken.Payload.Claims) { String claim = c.Value; if (claim.StartsWith("{\"loginname\":")) { payloadRoles.Add(serializer.Deserialize <TokenInfo>(claim)); } } var b_1 = payloadRoles.Where(a => !userRoles.Exists(t => a.roleId.Contains(t.roleId))).ToList().Count > 0; var b_2 = userRoles.Where(a => !payloadRoles.Exists(t => a.roleId.Contains(t.roleId))).ToList() .Count > 0; var b_3 = payloadRoles.Where(a => !userRoles.Exists(t => a.groupId.Contains(t.groupId))).ToList() .Count > 0; var b_4 = userRoles.Where(a => !payloadRoles.Exists(t => a.groupId.Contains(t.groupId))).ToList() .Count > 0; if (b_1 || b_2 || b_3 || b_4) { userInfos = null; msg = "令牌变更"; return(false); } if (!userRoles.Exists(t => t.baseUrl.Trim() != "" && t.baseUrl.Trim().ToUpper().Equals(requestURL.Trim().ToUpper()))) { userInfos = null; msg = "权限受限"; return(false); } userInfos = payloadRoles; msg = "有效"; return(true); } else // 过期 { userInfos = null; msg = "令牌过期"; return(false); } } catch (Exception e) { userInfos = null; msg = "鉴权失败:" + e.Message; return(false); } }