You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:23:12