如何修改.NET 8 Identity Bearer Token的各项属性?
在.NET 8 Identity中配置令牌与刷新令牌的核心参数
一、配置JWT令牌的基础参数(过期时间、颁发者、受众)
在Program.cs中配置JWT验证规则,同时在生成令牌时指定核心参数:
1. 配置验证规则
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { // 设置合法颁发者 ValidIssuer = builder.Configuration["Jwt:Issuer"], // 设置合法受众 ValidAudience = builder.Configuration["Jwt:Audience"], // 签名密钥(需与生成令牌时一致) IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])), // 启用过期验证 ValidateLifetime = true, // 关闭时钟偏差(严格验证过期时间) ClockSkew = TimeSpan.Zero }; });
2. 生成令牌时指定参数
在登录接口中创建JWT令牌,直接定义过期时间、颁发者和受众:
// 构造用户声明列表 var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.Email, user.Email) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"])); var signingCreds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); // 创建JWT令牌 var jwtToken = new JwtSecurityToken( issuer: _configuration["Jwt:Issuer"], audience: _configuration["Jwt:Audience"], claims: claims, expires: DateTime.UtcNow.AddMinutes(30), // 设置30分钟过期 signingCredentials: signingCreds); // 转换为字符串令牌 var tokenString = new JwtSecurityTokenHandler().WriteToken(jwtToken);
二、自定义刷新令牌的过期与管理
.NET 8 Identity未内置刷新令牌功能,需自行实现存储与验证:
1. 创建刷新令牌实体
public class RefreshToken { public int Id { get; set; } public string UserId { get; set; } public string Token { get; set; } public DateTime Expires { get; set; } // 刷新令牌过期时间 public bool IsRevoked { get; set; } public DateTime Created { get; set; } = DateTime.UtcNow; }
2. 生成与存储刷新令牌
登录成功后生成刷新令牌并保存到数据库:
var refreshToken = new RefreshToken { UserId = user.Id, Token = Guid.NewGuid().ToString(), Expires = DateTime.UtcNow.AddDays(7), // 设置7天过期 IsRevoked = false }; _context.RefreshTokens.Add(refreshToken); await _context.SaveChangesAsync();
3. 刷新令牌验证逻辑
在刷新接口中验证令牌有效性,若未过期则生成新的访问令牌:
var storedToken = await _context.RefreshTokens.FirstOrDefaultAsync(t => t.Token == refreshToken && !t.IsRevoked); if (storedToken == null || storedToken.Expires <= DateTime.UtcNow) { return Unauthorized("刷新令牌无效或已过期"); } // 生成新的访问令牌(逻辑同登录时的令牌生成) // ... // 可选:生成新的刷新令牌并替换旧令牌 storedToken.Token = Guid.NewGuid().ToString(); storedToken.Expires = DateTime.UtcNow.AddDays(7); await _context.SaveChangesAsync();
三、修改令牌中的关联声明属性
声明属性可通过两种方式配置:临时声明(仅当前令牌有效)和持久化声明(存储在用户表中)。
1. 添加/修改临时声明
在生成令牌时直接构造声明列表:
var claims = new List<Claim> { // 替换默认名称声明为全名 new Claim(ClaimTypes.Name, $"{user.FirstName} {user.LastName}"), // 添加自定义声明 new Claim("UserId", user.Id.ToString()), new Claim("IsEmailVerified", user.EmailConfirmed.ToString()), new Claim("Role", "Editor") };
2. 添加/修改持久化声明
通过UserManager给用户添加持久化声明,后续生成令牌时可直接读取:
// 给用户添加持久化声明 await _userManager.AddClaimAsync(user, new Claim("PreferredLanguage", "zh-CN")); // 生成令牌时读取用户的持久化声明 var userClaims = await _userManager.GetClaimsAsync(user); var claims = new List<Claim>(userClaims) { new Claim(ClaimTypes.Name, user.UserName) };
四、查看令牌内容
使用JwtSecurityTokenHandler解析令牌,提取所有参数和声明:
public IActionResult InspectToken(string token) { var handler = new JwtSecurityTokenHandler(); if (!handler.CanReadToken(token)) { return BadRequest("无效的JWT令牌"); } var jwtToken = handler.ReadJwtToken(token); return Ok(new { Issuer = jwtToken.Issuer, Audience = jwtToken.Audiences.FirstOrDefault(), ExpiresAt = jwtToken.ValidTo, Claims = jwtToken.Claims.Select(c => new { Type = c.Type, Value = c.Value }) }); }
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

