JwtUtil.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using Base;
  2. using Extensions;
  3. using Infrastructure.Model;
  4. using Microsoft.IdentityModel.Tokens;
  5. using Model.Base;
  6. using Newtonsoft.Json;
  7. using System.IdentityModel.Tokens.Jwt;
  8. using System.Security.Claims;
  9. using System.Text;
  10. namespace Util
  11. {
  12. /// <summary>
  13. /// 2023-8-29已从WebApi移至此
  14. /// </summary>
  15. public class JwtUtil
  16. {
  17. /// <summary>
  18. /// 获取用户身份信息
  19. /// </summary>
  20. /// <param name="httpContext"></param>
  21. /// <returns></returns>
  22. public static TokenModel GetLoginUser(HttpContext httpContext)
  23. {
  24. string token = httpContext.GetToken();
  25. if (!string.IsNullOrEmpty(token))
  26. {
  27. return ValidateJwtToken(ParseToken(token));
  28. }
  29. return null;
  30. }
  31. /// <summary>
  32. /// 生成token
  33. /// </summary>
  34. /// <param name="claims"></param>
  35. /// <returns></returns>
  36. public static string GenerateJwtToken(List<Claim> claims)
  37. {
  38. JwtSettings jwtSettings = new();
  39. AppSettings.Bind("JwtSettings", jwtSettings);
  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 = jwtSettings.TokenType,
  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 JwtSecurityToken? 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. return tokenHandler.ReadJwtToken(token);
  102. }
  103. catch (Exception ex)
  104. {
  105. Console.WriteLine(ex.Message);
  106. // return null if validation fails
  107. return null;
  108. }
  109. }
  110. /// <summary>
  111. /// jwt token校验
  112. /// </summary>
  113. /// <param name="jwtSecurityToken"></param>
  114. /// <returns></returns>
  115. public static TokenModel? ValidateJwtToken(JwtSecurityToken jwtSecurityToken)
  116. {
  117. try
  118. {
  119. if (jwtSecurityToken == null) return null;
  120. IEnumerable<Claim> claims = jwtSecurityToken?.Claims;
  121. TokenModel loginUser = null;
  122. var userData = claims.FirstOrDefault(x => x.Type == ClaimTypes.UserData)?.Value;
  123. if (userData != null)
  124. {
  125. loginUser = JsonConvert.DeserializeObject<TokenModel>(userData);
  126. loginUser.ExpireTime = jwtSecurityToken.ValidTo;
  127. }
  128. return loginUser;
  129. }
  130. catch (Exception ex)
  131. {
  132. Console.WriteLine(ex.Message);
  133. return null;
  134. }
  135. }
  136. /// <summary>
  137. ///组装Claims
  138. /// </summary>
  139. /// <param name="user"></param>
  140. /// <returns></returns>
  141. public static List<Claim> AddClaims(TokenModel user)
  142. {
  143. var claims = new List<Claim>()
  144. {
  145. new(ClaimTypes.PrimarySid, user.UserId.ToString()),
  146. new(ClaimTypes.NameIdentifier, user.UserId.ToString()),
  147. new(ClaimTypes.Name, user.Username),
  148. new(ClaimTypes.GroupSid, user.DeptId.ToString()),
  149. new(ClaimTypes.UserData, JsonConvert.SerializeObject(user))
  150. };
  151. return claims;
  152. }
  153. }
  154. }