C#生成JWT令牌验证时遇SecurityTokenNoExpirationException错误求助
问题
我正在开发一个通过JWT令牌实现认证的Web应用,在WebAssembly中调用Web API来生成和验证令牌。
令牌生成代码如下:
public string GenerateJwtToken(IEnumerable<Claim> claims, DateTime expireAt) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Value.Key)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken(issuer: jwtSettings.Value.Issuer, audience: jwtSettings.Value.Audience, claims: claims, expires: expireAt, signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); }
验证代码如下:
public ClaimsPrincipal? ValidateToken(string token) { var tokenHandler = new JwtSecurityTokenHandler(); var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Value.Key)); try { var tokenValidation = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = key, ValidateIssuer = true, ValidIssuer = jwtSettings.Value.Issuer, ValidateAudience = true, ValidAudience = jwtSettings.Value.Audience, ValidateLifetime = true }; SecurityToken validateToken; var principal = tokenHandler.ValidateToken(token, tokenValidation, out validateToken); return principal; } catch (Exception) { return null; } }
当我设置expiresAt为DateTime.UtcNow.AddDays(30)生成令牌后,验证时出现错误:
Microsoft.IdentityModel.Tokens.SecurityTokenNoExpirationException: IDX10225: Lifetime validation failed.
我的JWT配置已正确注入,请问该错误的原因是什么?
原因分析与解决方案
这个错误的核心原因是生成JWT时仅设置了过期时间(expires),未配置生效时间(notBefore)。
在默认的JWT生命周期验证逻辑中,需要同时检查nbf(生效时间)和exp(过期时间)两个字段。如果令牌只包含exp而缺少nbf,验证环节就会触发SecurityTokenNoExpirationException错误。
修复方法
修改令牌生成代码,在创建JwtSecurityToken实例时添加notBefore参数,设置为当前UTC时间即可:
public string GenerateJwtToken(IEnumerable<Claim> claims, DateTime expireAt) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Value.Key)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: jwtSettings.Value.Issuer, audience: jwtSettings.Value.Audience, claims: claims, notBefore: DateTime.UtcNow, // 添加生效时间参数 expires: expireAt, signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); }
补充说明
notBefore字段用于指定令牌最早可被验证的时间,设置为当前UTC时间可以避免客户端与服务器的时间差导致的验证异常。- 若确实不需要验证生效时间,可在
TokenValidationParameters中设置ValidateLifetime = false,但此操作会降低令牌安全性,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者Mat
相关产品推荐
相关产品推荐

