JwtUtil.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using Base;
  2. using Common;
  3. using Extensions;
  4. using Infrastructure.Model;
  5. using Microsoft.IdentityModel.Tokens;
  6. using Model.Base;
  7. using Newtonsoft.Json;
  8. using System.IdentityModel.Tokens.Jwt;
  9. using System.Security.Claims;
  10. using System.Text;
  11. namespace Util
  12. {
  13. /// <summary>
  14. /// 2023-8-29已从WebApi移至此
  15. /// </summary>
  16. public class JwtUtil
  17. {
  18. /// <summary>
  19. /// 获取用户身份信息
  20. /// </summary>
  21. /// <param name="httpContext"></param>
  22. /// <returns></returns>
  23. public static TokenModel 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. /// <returns></returns>
  37. public static string GenerateJwtToken(List<Claim> claims)
  38. {
  39. JwtSettings jwtSettings = new();
  40. AppSettings.Bind("JwtSettings", jwtSettings);
  41. var authTime = DateTime.Now;
  42. var expiresAt = authTime.AddMinutes(jwtSettings.Expire);
  43. var tokenHandler = new JwtSecurityTokenHandler();
  44. var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey);
  45. claims.Add(new Claim("Audience", jwtSettings.Audience));
  46. claims.Add(new Claim("Issuer", jwtSettings.Issuer));
  47. var tokenDescriptor = new SecurityTokenDescriptor
  48. {
  49. Subject = new ClaimsIdentity(claims),
  50. Issuer = jwtSettings.Issuer,
  51. Audience = jwtSettings.Audience,
  52. IssuedAt = authTime,//token生成时间
  53. Expires = expiresAt,
  54. //NotBefore = authTime,
  55. TokenType = jwtSettings.TokenType,
  56. //对称秘钥,签名证书
  57. SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
  58. };
  59. var token = tokenHandler.CreateToken(tokenDescriptor);
  60. return tokenHandler.WriteToken(token);
  61. }
  62. /// <summary>
  63. /// 验证Token
  64. /// </summary>
  65. /// <returns></returns>
  66. public static TokenValidationParameters ValidParameters()
  67. {
  68. JwtSettings jwtSettings = new();
  69. AppSettings.Bind("JwtSettings", jwtSettings);
  70. if (jwtSettings == null || jwtSettings.SecretKey.IsEmpty())
  71. {
  72. throw new Exception("JwtSettings获取失败");
  73. }
  74. var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey);
  75. var tokenDescriptor = new TokenValidationParameters
  76. {
  77. ValidateIssuerSigningKey = true,
  78. ValidateIssuer = true,
  79. ValidateAudience = true,
  80. ValidIssuer = jwtSettings.Issuer,
  81. ValidAudience = jwtSettings.Audience,
  82. IssuerSigningKey = new SymmetricSecurityKey(key),
  83. ValidateLifetime = true,//是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
  84. ClockSkew = TimeSpan.FromSeconds(30)
  85. //RequireExpirationTime = true,//过期时间
  86. };
  87. return tokenDescriptor;
  88. }
  89. /// <summary>
  90. /// 从令牌中获取数据声明
  91. /// </summary>
  92. /// <param name="token">令牌</param>
  93. /// <returns></returns>
  94. public static JwtSecurityToken? ParseToken(string token)
  95. {
  96. var tokenHandler = new JwtSecurityTokenHandler();
  97. var validateParameter = ValidParameters();
  98. token = token.Replace("Bearer ", "");
  99. try
  100. {
  101. tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken);
  102. return tokenHandler.ReadJwtToken(token);
  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="jwtSecurityToken"></param>
  115. /// <returns></returns>
  116. public static TokenModel? ValidateJwtToken(JwtSecurityToken jwtSecurityToken)
  117. {
  118. try
  119. {
  120. if (jwtSecurityToken == null) return null;
  121. IEnumerable<Claim> claims = jwtSecurityToken?.Claims;
  122. TokenModel loginUser = null;
  123. var userData = claims.FirstOrDefault(x => x.Type == ClaimTypes.UserData)?.Value;
  124. if (userData != null)
  125. {
  126. loginUser = JsonConvert.DeserializeObject<TokenModel>(userData);
  127. loginUser.ExpireTime = jwtSecurityToken.ValidTo;
  128. }
  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(TokenModel user)
  143. {
  144. var claims = new List<Claim>()
  145. {
  146. new(ClaimTypes.PrimarySid, user.userId.ToString()),
  147. new(ClaimTypes.NameIdentifier, user.userId.ToString()),
  148. new(ClaimTypes.Name, Function.CheckNull(user.username)),
  149. new(ClaimTypes.GroupSid, user.deptId.ToString()),
  150. new(ClaimTypes.UserData, JsonConvert.SerializeObject(user))
  151. };
  152. return claims;
  153. }
  154. }
  155. }