TokenHelper.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using Microsoft.Extensions.Options;
  2. using Microsoft.IdentityModel.Tokens;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IdentityModel.Tokens.Jwt;
  6. using System.Linq;
  7. using System.Security.Claims;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using Ropin.Inspection.Model;
  11. using Ropin.Inspection.Model.ViewModel;
  12. namespace Ropin.Inspection.Api.Common.Token
  13. {
  14. public enum TokenType
  15. {
  16. AccessToken = 1,
  17. RefreshToken = 2
  18. }
  19. public class TokenHelper : ITokenHelper
  20. {
  21. private readonly IOptions<JWTConfig> _options;
  22. public TokenHelper(IOptions<JWTConfig> options)
  23. {
  24. _options = options;
  25. }
  26. public Token CreateAccessToken(TsysUserDetailViewModel user)
  27. {
  28. Claim[] claims = { new Claim(ClaimTypes.NameIdentifier, user.C_UserID.ToString()), new Claim(ClaimTypes.Name, user.C_Name), new Claim(ClaimTypes.Role, user.RoleIds) ,new Claim(ClaimTypes.PrimaryGroupSid, user.C_OrgCode.ToString()) };
  29. return CreateToken(claims, TokenType.AccessToken);
  30. }
  31. public ComplexToken CreateToken(TsysUserDetailViewModel user)
  32. {
  33. Claim[] claims = {
  34. new Claim(ClaimTypes.NameIdentifier, user.C_UserID.ToString()),
  35. new Claim(ClaimTypes.Name, user.C_Name),
  36. new Claim(ClaimTypes.Role, user.RoleNames??""),
  37. new Claim(ClaimTypes.Rsa, user.C_LicenseCode),
  38. new Claim(ClaimTypes.Sid, user.LicenseTypeCode),
  39. new Claim(ClaimTypes.Actor, user.OrgTypeCode),
  40. new Claim(ClaimTypes.PrimaryGroupSid, user.C_OrgCode.ToString())};
  41. return new ComplexToken
  42. {
  43. AccessToken = CreateToken(claims, TokenType.AccessToken),
  44. RefreshToken = CreateToken(claims, TokenType.RefreshToken),
  45. User = user
  46. };
  47. }
  48. /// <summary>
  49. /// 用于创建AccessToken和RefreshToken。
  50. /// 这里AccessToken和RefreshToken只是过期时间不同
  51. /// 因为RefreshToken只是用于刷新AccessToken,其内容可以简单一些。
  52. /// 而AccessToken可能会附加一些其他的Claim。
  53. /// </summary>
  54. /// <param name="claims"></param>
  55. /// <param name="tokenType"></param>
  56. /// <returns></returns>
  57. private Token CreateToken(Claim[] claims, TokenType tokenType)
  58. {
  59. claims = claims.Append(new Claim("TokenType", tokenType.ToString())).ToArray();
  60. var now = DateTime.Now;
  61. var expires = now.Add(TimeSpan.FromMinutes(tokenType.Equals(TokenType.AccessToken) ? _options.Value.AccessTokenExpiresMinutes : _options.Value.RefreshTokenExpiresMinutes));
  62. var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey));
  63. var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
  64. var token = new JwtSecurityToken(
  65. issuer: _options.Value.Issuer,
  66. audience: _options.Value.Audience,
  67. claims: claims,
  68. notBefore: now,
  69. expires: expires,
  70. //签名证书
  71. signingCredentials: creds);
  72. //signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey)), SecurityAlgorithms.HmacSha256));
  73. return new Token { TokenContent = new JwtSecurityTokenHandler().WriteToken(token), Expires = expires };
  74. }
  75. public ComplexToken RefreshTokenByClaimsPrincipal(ClaimsPrincipal claimsPrincipal)
  76. {
  77. if (claimsPrincipal!=null)
  78. {
  79. //claimsPrincipal.Claims.Any(m => m.Type.Equals("TokenType") && m.Value.Equals(TokenType.RefreshToken.ToString()))
  80. if (claimsPrincipal.Claims.Any(m => m.Type == ("TokenType") && m.Value == (TokenType.RefreshToken.ToString())))
  81. {
  82. var code = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.NameIdentifier));
  83. var name = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Name));
  84. var RoleNames = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Role));
  85. var License = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Rsa));
  86. var LicenseTypeCode = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Sid));
  87. var OrgTypeCode = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Actor));
  88. var PrimaryGroupSid = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.PrimaryGroupSid));
  89. if (null != code)
  90. {
  91. //return CreateAccessToken(new TsysUserDetailViewModel { C_UserID = Guid.Parse(code.Value) , C_Name = name.Value ,RoleNames = RoleNames.Value});
  92. return CreateToken(new TsysUserDetailViewModel
  93. {
  94. C_UserID = Guid.Parse(code.Value),
  95. C_Name = name.Value,
  96. RoleNames = RoleNames.Value,
  97. C_OrgCode = Guid.Parse(PrimaryGroupSid.Value),
  98. C_LicenseCode = License.Value,
  99. LicenseTypeCode = LicenseTypeCode.Value,
  100. OrgTypeCode = OrgTypeCode.Value
  101. });
  102. }
  103. }
  104. }
  105. return null;
  106. }
  107. public ComplexToken RefreshToken(string refreshToken)
  108. {
  109. ClaimsPrincipal claimsPrincipal = GetClaimsPrincipalByToken(refreshToken);
  110. return RefreshTokenByClaimsPrincipal(claimsPrincipal);
  111. }
  112. private ClaimsPrincipal GetClaimsPrincipalByToken(string token)
  113. {
  114. try
  115. {
  116. var tokenValidationParameters = new TokenValidationParameters
  117. {
  118. ValidateIssuer = false,
  119. ValidateAudience = false,
  120. ValidateIssuerSigningKey = true,
  121. IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey)),
  122. ClockSkew = TimeSpan.Zero,
  123. ValidateLifetime = false // 不验证过期时间!!!
  124. };
  125. var jwtTokenHandler = new JwtSecurityTokenHandler();
  126. var claimsPrincipal =
  127. jwtTokenHandler.ValidateToken(token, tokenValidationParameters, out var validatedToken);
  128. var validatedSecurityAlgorithm = validatedToken is JwtSecurityToken jwtSecurityToken
  129. && jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256,
  130. StringComparison.InvariantCultureIgnoreCase);
  131. return validatedSecurityAlgorithm ? claimsPrincipal : null;
  132. }
  133. catch
  134. {
  135. return null;
  136. }
  137. }
  138. public Token RefreshToken(ClaimsPrincipal claimsPrincipal)
  139. {
  140. if (claimsPrincipal.Claims.Any(m => m.Type.Equals("TokenType") && m.Value.Equals(TokenType.RefreshToken.ToString())))
  141. {
  142. var code = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.NameIdentifier));
  143. var name = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Name));
  144. var RoleNames = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Role));
  145. var PrimaryGroupSid = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.PrimaryGroupSid));
  146. var LicenseCode = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Rsa));
  147. var LicenseTypeCode = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Sid));
  148. var OrgTypeCode = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Actor));
  149. if (null != code)
  150. {
  151. return CreateAccessToken(new TsysUserDetailViewModel { C_UserID = Guid.Parse(code.Value) ,C_LicenseCode = LicenseCode.Value, LicenseTypeCode = LicenseTypeCode.Value, C_Name = name.Value ,RoleNames = RoleNames.Value, C_OrgCode = Guid.Parse(PrimaryGroupSid.Value),OrgTypeCode = OrgTypeCode.Value });
  152. }
  153. }
  154. return null;
  155. }
  156. }
  157. }