JwtUtil.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using Infrastructure;
  2. using Infrastructure.Extensions;
  3. using Microsoft.IdentityModel.Tokens;
  4. using Newtonsoft.Json;
  5. using System.IdentityModel.Tokens.Jwt;
  6. using System.Security.Claims;
  7. using System.Text;
  8. using ZR.Admin.WebApi.Extensions;
  9. using ZR.Model.System;
  10. using ZR.Service.System;
  11. namespace ZR.Admin.WebApi.Framework
  12. {
  13. /// <summary>
  14. /// 2020-11-20
  15. /// </summary>
  16. public class JwtUtil
  17. {
  18. /// <summary>
  19. /// 获取用户身份信息
  20. /// </summary>
  21. /// <param name="httpContext"></param>
  22. /// <returns></returns>
  23. public static LoginUser GetLoginUser(HttpContext httpContext)
  24. {
  25. string token = httpContext.GetToken();
  26. if (!string.IsNullOrEmpty(token))
  27. {
  28. return ValidateJwtToken(ParseToken(token));
  29. }
  30. return null;
  31. }
  32. /// <summary>
  33. /// 生成token
  34. /// </summary>
  35. /// <param name="claims"></param>
  36. /// <param name="jwtSettings"></param>
  37. /// <returns></returns>
  38. public static string GenerateJwtToken(List<Claim> claims, JwtSettings jwtSettings)
  39. {
  40. var authTime = DateTime.Now;
  41. var expiresAt = authTime.AddMinutes(jwtSettings.Expire);
  42. var tokenHandler = new JwtSecurityTokenHandler();
  43. var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey);
  44. claims.Add(new Claim("Audience", jwtSettings.Audience));
  45. claims.Add(new Claim("Issuer", jwtSettings.Issuer));
  46. var tokenDescriptor = new SecurityTokenDescriptor
  47. {
  48. Subject = new ClaimsIdentity(claims),
  49. Issuer = jwtSettings.Issuer,
  50. Audience = jwtSettings.Audience,
  51. IssuedAt = authTime,//token生成时间
  52. Expires = expiresAt,
  53. //NotBefore = authTime,
  54. TokenType = "Bearer",
  55. //对称秘钥,签名证书
  56. SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
  57. };
  58. var token = tokenHandler.CreateToken(tokenDescriptor);
  59. return tokenHandler.WriteToken(token);
  60. }
  61. /// <summary>
  62. /// 验证Token
  63. /// </summary>
  64. /// <returns></returns>
  65. public static TokenValidationParameters ValidParameters()
  66. {
  67. JwtSettings jwtSettings = new();
  68. AppSettings.Bind("JwtSettings", jwtSettings);
  69. if (jwtSettings == null || jwtSettings.SecretKey.IsEmpty())
  70. {
  71. throw new Exception("JwtSettings获取失败");
  72. }
  73. var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey);
  74. var tokenDescriptor = new TokenValidationParameters
  75. {
  76. ValidateIssuerSigningKey = true,
  77. ValidateIssuer = true,
  78. ValidateAudience = true,
  79. ValidIssuer = jwtSettings.Issuer,
  80. ValidAudience = jwtSettings.Audience,
  81. IssuerSigningKey = new SymmetricSecurityKey(key),
  82. ValidateLifetime = true,//是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
  83. ClockSkew = TimeSpan.FromSeconds(30)
  84. //RequireExpirationTime = true,//过期时间
  85. };
  86. return tokenDescriptor;
  87. }
  88. /// <summary>
  89. /// 从令牌中获取数据声明
  90. /// </summary>
  91. /// <param name="token">令牌</param>
  92. /// <returns></returns>
  93. public static IEnumerable<Claim>? ParseToken(string token)
  94. {
  95. var tokenHandler = new JwtSecurityTokenHandler();
  96. var validateParameter = ValidParameters();
  97. token = token.Replace("Bearer ", "");
  98. try
  99. {
  100. tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken);
  101. var jwtToken = tokenHandler.ReadJwtToken(token);
  102. return jwtToken.Claims;
  103. }
  104. catch (Exception ex)
  105. {
  106. Console.WriteLine(ex.Message);
  107. // return null if validation fails
  108. return null;
  109. }
  110. }
  111. /// <summary>
  112. /// jwt token校验
  113. /// </summary>
  114. /// <param name="jwtToken"></param>
  115. /// <returns></returns>
  116. public static LoginUser? ValidateJwtToken(IEnumerable<Claim> jwtToken)
  117. {
  118. try
  119. {
  120. var userData = jwtToken.FirstOrDefault(x => x.Type == ClaimTypes.UserData).Value;
  121. var loginUser = JsonConvert.DeserializeObject<LoginUser>(userData);
  122. var permissions = CacheService.GetUserPerms(GlobalConstant.UserPermKEY + loginUser?.UserId);
  123. if (loginUser?.UserName == GlobalConstant.AdminRole)
  124. {
  125. permissions = new List<string>() { GlobalConstant.AdminPerm };
  126. }
  127. if (permissions == null) return null;
  128. loginUser.Permissions = permissions;
  129. return loginUser;
  130. }
  131. catch (Exception ex)
  132. {
  133. Console.WriteLine(ex.Message);
  134. return null;
  135. }
  136. }
  137. /// <summary>
  138. ///组装Claims
  139. /// </summary>
  140. /// <param name="user"></param>
  141. /// <returns></returns>
  142. public static List<Claim> AddClaims(LoginUser user)
  143. {
  144. if (user?.Permissions.Count > 50)
  145. {
  146. user.Permissions = new List<string>();
  147. }
  148. var claims = new List<Claim>()
  149. {
  150. new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()),
  151. new Claim(ClaimTypes.Name, user.UserName),
  152. new Claim(ClaimTypes.UserData, JsonConvert.SerializeObject(user))
  153. };
  154. return claims;
  155. }
  156. }
  157. }