using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.AspNetCore.Authentication.JwtBearer; using Newtonsoft.Json; using Microsoft.AspNetCore.Authorization; using Shentun.Utilities.Encrypt; using NPOI.SS.Formula.Functions; using Shentun.Utilities.Enums; namespace Shentun.WebApi.Service { public class JwtHelper { public string SecurityKey; public JwtHelper() { var jwtConfig = new JwtConfig(); SecurityKey = jwtConfig.SecurityKey; } public double GetExpiration(ClientAppType clientAppType) { var jwtConfig = new JwtConfig(); // 过期时间 double expMin; switch (clientAppType) { case ClientAppType.Web: expMin = jwtConfig.WebExpiration; break; case ClientAppType.Mobile: expMin = jwtConfig.MobileExpiration; break; case ClientAppType.Mini: expMin = jwtConfig.MiniExpiration; break; case ClientAppType.SelfMachine: expMin = jwtConfig.SelfMachineExpiration; break; case ClientAppType.Desktop: expMin = jwtConfig.DesktopExpiration; break; default: expMin = jwtConfig.OtherExpiration; break; } return expMin; } /// /// 获取JWT令牌 /// /// /// /// public string GetJwt(IEnumerable claims,ClientAppType clientAppType,bool isRefreshToken = false) { var dateTime = DateTime.UtcNow;//世界时间 //秘钥 var jwtConfig = new JwtConfig(); var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); // 过期时间 double expMin; switch (clientAppType) { case ClientAppType.Web: expMin = jwtConfig.WebExpiration; break; case ClientAppType.Mobile: expMin = jwtConfig.MobileExpiration; break; case ClientAppType.Mini: expMin = jwtConfig.MiniExpiration; break; case ClientAppType.SelfMachine: expMin = jwtConfig.SelfMachineExpiration; break; case ClientAppType.Desktop: expMin = jwtConfig.DesktopExpiration; break; default: expMin = jwtConfig.OtherExpiration; break; } if (isRefreshToken) { expMin = expMin * 2; } DateTime expTime = dateTime.AddMinutes(expMin); var jwt = new JwtSecurityToken( issuer: jwtConfig.Issuer,//颁发者 audience: jwtConfig.Audience,//颁发给 claims: claims, //声明集合 notBefore: dateTime,//生效时间,这里必须使用世界时间 expires: expTime,//过期时间,这里必须使用世界时间 signingCredentials: creds); var jwtHandler = new JwtSecurityTokenHandler(); var encodedJwt = jwtHandler.WriteToken(jwt); encodedJwt = $"{JwtBearerDefaults.AuthenticationScheme} {encodedJwt}"; //encodedJwt = AESHelper.Encode(encodedJwt, SecurityKey.Substring(0,16)); return encodedJwt; } /// /// 获取TokenValidationParameters /// /// public TokenValidationParameters GetTokenValidationParameters() { var jwtConfig = new JwtConfig(); TokenValidationParameters tokenValidationParameters = new TokenValidationParameters { ValidIssuer = jwtConfig.Issuer,//颁发者 ValidAudience = jwtConfig.Audience,//颁发给 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey)), /***********************************TokenValidationParameters的参数默认值***********************************/ RequireSignedTokens = true, // SaveSigninToken = false, // ValidateActor = false, // 将下面两个参数设置为false,可以不验证Issuer和Audience,但是不建议这样做。 ValidateAudience = true,//颁发给验证 ValidateIssuer = true,//颁发者验证 ValidateIssuerSigningKey = true, // 是否要求Token的Claims中必须包含 Expires RequireExpirationTime = true, // 允许的服务器时间偏移量 ClockSkew = TimeSpan.FromSeconds(1), // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比 ValidateLifetime = true }; return tokenValidationParameters; } public JwtSecurityToken GetValidatedToken(string jwtStr) { var jwtHandler = new JwtSecurityTokenHandler(); if (jwtStr.StartsWith(JwtBearerDefaults.AuthenticationScheme)) jwtStr = jwtStr.ToString().Substring(JwtBearerDefaults.AuthenticationScheme.Length).Trim(); jwtHandler.ValidateToken(jwtStr, GetTokenValidationParameters(), out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; return jwtToken; } } }