- 在 AuthHelper 中添加 JTI (JWT ID) 生成逻辑 - 为每个 JWT 令牌分配唯一标识符 - 实现 JTI 声明的自动添加功能 - 集成到现有的令牌创建流程中 - 支持后续的令牌黑名单管理需求
114 lines
3.9 KiB
C#
114 lines
3.9 KiB
C#
using Microsoft.IdentityModel.Tokens;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.Net.Http;
|
|
using System.Security.Claims;
|
|
using System.Text;
|
|
using YLErp;
|
|
|
|
namespace YLErp.Helpers
|
|
{
|
|
/// <summary>
|
|
/// 用户认证帮助类
|
|
/// </summary>
|
|
public class AuthHelper
|
|
{
|
|
public const string CookieAuthType = "yc_identity";
|
|
|
|
public const string JwtAuthType = "yc_mapi";
|
|
|
|
/// <summary>
|
|
/// 登录Token过期时间(秒)
|
|
/// </summary>
|
|
public static int ExpireInSeconds => PS.Config?.ErpElement?.LoginTokenExpireSeconds ?? 3600 * 10; // 默认10小时
|
|
|
|
public const string JwtIssuer = "yilian";
|
|
|
|
public const string JwtAudience = "yilian";
|
|
|
|
public const string JwtSecretKey = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrkzI1NiJ9eyJjbGFTT";
|
|
|
|
public const string JwtUserToken = "###jwt###";
|
|
|
|
/// <summary>
|
|
/// 创建jwt令牌
|
|
/// </summary>
|
|
public static string CreateJwtToken(ClaimsIdentity identity)
|
|
{
|
|
var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(JwtSecretKey));
|
|
|
|
// 添加 JTI (JWT ID) 用于黑名单机制
|
|
var claims = new ClaimsIdentity(identity);
|
|
if (!claims.HasClaim(c => c.Type == "jti"))
|
|
{
|
|
claims.AddClaim(new Claim("jti", Guid.NewGuid().ToString("N")));
|
|
}
|
|
|
|
var tokenDescriptor = new SecurityTokenDescriptor
|
|
{
|
|
Subject = claims,
|
|
Expires = DateTime.UtcNow.AddSeconds(ExpireInSeconds),
|
|
Issuer = JwtIssuer,
|
|
Audience = JwtAudience,
|
|
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature)
|
|
};
|
|
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
|
|
var token = tokenHandler.CreateToken(tokenDescriptor);
|
|
|
|
return tokenHandler.WriteToken(token);
|
|
}
|
|
|
|
public static string CreateJwtToken2(ClaimsIdentity identity)
|
|
{
|
|
var key = new SymmetricSecurityKey(Convert.FromBase64String(JwtSecretKey));
|
|
|
|
// 添加 JTI (JWT ID) 用于黑名单机制
|
|
var claims = new ClaimsIdentity(identity);
|
|
if (!claims.HasClaim(c => c.Type == "jti"))
|
|
{
|
|
claims.AddClaim(new Claim("jti", Guid.NewGuid().ToString("N")));
|
|
}
|
|
|
|
var tokenDescriptor = new SecurityTokenDescriptor
|
|
{
|
|
Subject = claims,
|
|
Expires = DateTime.UtcNow.AddSeconds(ExpireInSeconds),
|
|
IssuedAt = DateTime.Now,
|
|
Issuer = JwtIssuer,
|
|
Audience = JwtAudience,
|
|
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha512)
|
|
};
|
|
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
|
|
var token = tokenHandler.CreateToken(tokenDescriptor);
|
|
|
|
return tokenHandler.WriteToken(token);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 解析JWT token
|
|
/// </summary>
|
|
/// <param name="token">JWT token字符串</param>
|
|
/// <returns>解析后的JWT token对象</returns>
|
|
public static JwtSecurityToken ParseJwtToken(string token)
|
|
{
|
|
var tokenHandler = new JwtSecurityTokenHandler();
|
|
return tokenHandler.ReadJwtToken(token);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查token是否需要续期
|
|
/// </summary>
|
|
/// <param name="token">JWT token对象</param>
|
|
/// <param name="thresholdSeconds">续期阈值(秒)</param>
|
|
/// <returns>是否需要续期</returns>
|
|
public static bool NeedRefreshToken(JwtSecurityToken token, int thresholdSeconds = 3600)
|
|
{
|
|
var timeUntilExpiry = token.ValidTo - DateTime.UtcNow;
|
|
return timeUntilExpiry.TotalSeconds < thresholdSeconds;
|
|
}
|
|
}
|
|
}
|