You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
6.1 KiB

2 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Microsoft.IdentityModel.Tokens;
  6. using System.IdentityModel.Tokens.Jwt;
  7. using System.Security.Claims;
  8. using System.Text;
  9. using Microsoft.AspNetCore.Authentication.JwtBearer;
  10. using Newtonsoft.Json;
  11. using Microsoft.AspNetCore.Authorization;
  12. using Shentun.Utilities.Encrypt;
  13. using NPOI.SS.Formula.Functions;
  14. using Shentun.Utilities.Enums;
  15. namespace Shentun.WebApi.Service
  16. {
  17. public class JwtHelper
  18. {
  19. public string SecurityKey;
  20. public JwtHelper()
  21. {
  22. var jwtConfig = new JwtConfig();
  23. SecurityKey = jwtConfig.SecurityKey;
  24. }
  25. public double GetExpiration(ClientAppType clientAppType)
  26. {
  27. var jwtConfig = new JwtConfig();
  28. // 过期时间
  29. double expMin;
  30. switch (clientAppType)
  31. {
  32. case ClientAppType.Web:
  33. expMin = jwtConfig.WebExpiration;
  34. break;
  35. case ClientAppType.Mobile:
  36. expMin = jwtConfig.MobileExpiration;
  37. break;
  38. case ClientAppType.Mini:
  39. expMin = jwtConfig.MiniExpiration;
  40. break;
  41. case ClientAppType.SelfMachine:
  42. expMin = jwtConfig.SelfMachineExpiration;
  43. break;
  44. case ClientAppType.Desktop:
  45. expMin = jwtConfig.DesktopExpiration;
  46. break;
  47. default:
  48. expMin = jwtConfig.OtherExpiration;
  49. break;
  50. }
  51. return expMin;
  52. }
  53. /// <summary>
  54. /// 获取JWT令牌
  55. /// </summary>
  56. /// <param name="claims"></param>
  57. /// <param name="clientAppType"></param>
  58. /// <returns></returns>
  59. public string GetJwt(IEnumerable<Claim> claims,ClientAppType clientAppType,bool isRefreshToken = false)
  60. {
  61. var dateTime = DateTime.UtcNow;//世界时间
  62. //秘钥
  63. var jwtConfig = new JwtConfig();
  64. var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey));
  65. var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  66. // 过期时间
  67. double expMin;
  68. switch (clientAppType)
  69. {
  70. case ClientAppType.Web:
  71. expMin = jwtConfig.WebExpiration;
  72. break;
  73. case ClientAppType.Mobile:
  74. expMin = jwtConfig.MobileExpiration;
  75. break;
  76. case ClientAppType.Mini:
  77. expMin = jwtConfig.MiniExpiration;
  78. break;
  79. case ClientAppType.SelfMachine:
  80. expMin = jwtConfig.SelfMachineExpiration;
  81. break;
  82. case ClientAppType.Desktop:
  83. expMin = jwtConfig.DesktopExpiration;
  84. break;
  85. default:
  86. expMin = jwtConfig.OtherExpiration;
  87. break;
  88. }
  89. if (isRefreshToken)
  90. {
  91. expMin = expMin * 2;
  92. }
  93. DateTime expTime = dateTime.AddMinutes(expMin);
  94. var jwt = new JwtSecurityToken(
  95. issuer: jwtConfig.Issuer,//颁发者
  96. audience: jwtConfig.Audience,//颁发给
  97. claims: claims, //声明集合
  98. notBefore: dateTime,//生效时间,这里必须使用世界时间
  99. expires: expTime,//过期时间,这里必须使用世界时间
  100. signingCredentials: creds);
  101. var jwtHandler = new JwtSecurityTokenHandler();
  102. var encodedJwt = jwtHandler.WriteToken(jwt);
  103. encodedJwt = $"{JwtBearerDefaults.AuthenticationScheme} {encodedJwt}";
  104. //encodedJwt = AESHelper.Encode(encodedJwt, SecurityKey.Substring(0,16));
  105. return encodedJwt;
  106. }
  107. /// <summary>
  108. /// 获取TokenValidationParameters
  109. /// </summary>
  110. /// <returns></returns>
  111. public TokenValidationParameters GetTokenValidationParameters()
  112. {
  113. var jwtConfig = new JwtConfig();
  114. TokenValidationParameters tokenValidationParameters = new TokenValidationParameters
  115. {
  116. ValidIssuer = jwtConfig.Issuer,//颁发者
  117. ValidAudience = jwtConfig.Audience,//颁发给
  118. IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey)),
  119. /***********************************TokenValidationParameters的参数默认值***********************************/
  120. RequireSignedTokens = true,
  121. // SaveSigninToken = false,
  122. // ValidateActor = false,
  123. // 将下面两个参数设置为false,可以不验证Issuer和Audience,但是不建议这样做。
  124. ValidateAudience = true,//颁发给验证
  125. ValidateIssuer = true,//颁发者验证
  126. ValidateIssuerSigningKey = true,
  127. // 是否要求Token的Claims中必须包含 Expires
  128. RequireExpirationTime = true,
  129. // 允许的服务器时间偏移量
  130. ClockSkew = TimeSpan.FromSeconds(1),
  131. // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
  132. ValidateLifetime = true
  133. };
  134. return tokenValidationParameters;
  135. }
  136. public JwtSecurityToken GetValidatedToken(string jwtStr)
  137. {
  138. var jwtHandler = new JwtSecurityTokenHandler();
  139. if (jwtStr.StartsWith(JwtBearerDefaults.AuthenticationScheme))
  140. jwtStr = jwtStr.ToString().Substring(JwtBearerDefaults.AuthenticationScheme.Length).Trim();
  141. jwtHandler.ValidateToken(jwtStr, GetTokenValidationParameters(), out SecurityToken validatedToken);
  142. var jwtToken = (JwtSecurityToken)validatedToken;
  143. return jwtToken;
  144. }
  145. }
  146. }