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

.NET 8集成测试中AddJwtBearer自定义TimeProvider不生效问题

如何让AddJwtBearer使用自定义TimeProvider进行JWT验证?

问题概述

为加速.NET 8集成测试,通过实现自定义TimeProvider(ClockMutable,同时实现IClock接口)模拟未来时间,生成的JWT令牌时间戳(nbf/exp)符合预期,但验证时始终失败,返回:

www-authenticate: Bearer error="invalid_token",error_description="The token is not valid before '07/26/2024 17:56:05'"

已将自定义TimeProvider实例传入AddJwtBearer配置,但认证中间件仍使用系统时间,且自定义实例的方法未被触发。可复现示例运行后,日志明确显示验证逻辑使用系统当前时间而非自定义时间:

info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
      Failed to validate the token.
      Microsoft.IdentityModel.Tokens.SecurityTokenNotYetValidException: IDX10222: Lifetime validation failed. The token is not yet valid. ValidFrom (UTC): '2025-01-01 00:00:00', Current time (UTC): '2024-07-27 14:18:40'.

核心原因

排查确认:JwtBearerOptions.TimeProvider属性目前并未被底层JWT验证逻辑实际调用,相关功能仍处于开发阶段,尚未合并到正式发布版本。

临时解决方案

方案1:调整ClockSkew(适用于小幅度时间偏移场景)

如果测试中的时间偏移范围不大,可临时增大ClockSkew参数,让验证逻辑容忍时间差:

builder.Services.AddAuthentication()
    .AddJwtBearer(x => {
        // 其他配置...
        x.TokenValidationParameters = new TokenValidationParameters {
            // 其他参数...
            ClockSkew = TimeSpan.FromHours(24) // 根据测试需求调整
        };
    });

注意:此方法仅适合小幅度时间调整,且仅建议在测试环境使用,避免生产环境引入安全风险。

方案2:自定义SecurityTokenValidator(支持任意时间跳转)

通过替换默认验证器,完全接管时间验证逻辑:

  1. 实现自定义验证器:
public class CustomJwtValidator : JwtSecurityTokenValidator
{
    private readonly TimeProvider _customTimeProvider;

    public CustomJwtValidator(TimeProvider timeProvider)
    {
        _customTimeProvider = timeProvider;
    }

    public override ClaimsPrincipal ValidateToken(string token, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    {
        // 克隆验证参数并替换当前时间
        var modifiedParams = validationParameters.Clone();
        var currentUtcTime = _customTimeProvider.GetUtcNow().UtcDateTime;
        modifiedParams.ValidFrom = currentUtcTime;
        modifiedParams.ValidTo = currentUtcTime;

        return base.ValidateToken(token, modifiedParams, out validatedToken);
    }
}
  1. 注册并替换默认验证器:
// 注册自定义验证器
builder.Services.AddSingleton<ISecurityTokenValidator>(sp => 
    new CustomJwtValidator(ClockMutable.Default));

builder.Services.AddAuthentication()
    .AddJwtBearer(x => {
        // 其他配置...
        // 清除默认验证器,添加自定义实现
        x.SecurityTokenValidators.Clear();
        x.SecurityTokenValidators.Add(sp => sp.GetRequiredService<ISecurityTokenValidator>());
    });

此方案可完全控制验证时使用的时间,支持任意幅度的时间跳转测试。

方案3:等待官方功能发布

待相关功能开发完成并合并到正式版本后,直接使用JwtBearerOptions.TimeProvider即可生效。

内容的提问来源于stack exchange,提问作者Arokh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 15:29:51