JwtSecurityToken 返回错误的过期时间

Posted

技术标签:

【中文标题】JwtSecurityToken 返回错误的过期时间【英文标题】:JwtSecurityToken returning wrong expiration time 【发布时间】:2018-05-22 13:25:21 【问题描述】:

我需要检查我的JwtSecurityToken 是否过期。

我正在使用System.IdentityModel.Tokens.Jwt 库。

当像这样创建JwtSecurityToken 时:

var token = new JwtSecurityToken(
    issuer: token_issuer,
    audience: token_audience,
    claims: claims,
    expires: DateTime.Now.AddMinutes(15),                
    signingCredentials: creds
    );

检查它的生命周期,我比当前时间晚了 2 小时

我以这种方式检查生命周期(仅用于测试目的):

var lifeTime = new JwtSecurityTokenHandler().ReadToken(token).ValidTo;

还有我的验证方法:

private static bool ValidateToken(string token)

    try
    
        TokenValidationParameters validationParameters = new TokenValidationParameters
        
            IssuerSigningKey = new SymmetricSecurityKey(token_salt),
            ValidAudience = token_audience,
            ValidIssuer = token_issuer,
            RequireExpirationTime = true
        ;

        var lifeTime = new JwtSecurityTokenHandler().ReadToken(token).ValidTo;

        ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(token_last, validationParameters, out SecurityToken validatedToken);

        return true;
    
    catch(Exception ex)
    

    

    return false;


谁能解释发生了什么或者我做错了什么?


编辑(用于解释目的)

测试 1

我的设备当前时间:10:06 使用expiration = DateTime.Now.AddSeconds(5); 令牌的生命周期 = 12:06:10 和种类 = UTC 验证正常。

测试 2

我的设备当前时间:10:16 使用expiration = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Utc).AddSeconds(5); 令牌的生命周期 = 10:16:12 和种类 = UTC 验证失败: Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired. ValidTo: '12/11/2017 10:16:12' Current time: '12/11/2017 12:18:40'.

测试 3

使用expiration = DateTime.UtcNow.AddSeconds(5); 令牌的生命周期 = 13:07:10 和种类 = UTC 验证正常。

但是为什么如果我运行验证时是 13:12 并且令牌的生命周期是 13:07,验证会通过?到期时是否有最低投注时间?

【问题讨论】:

你能解释一下这是哪个库吗? @ParvSharma 问题已编辑。 请看我的回答 "检查它的生命周期,我比当前时间晚了 2 小时。"你如何准确地检查它的寿命? (无论如何,我建议您使用DateTime.UtcNow,请注意...) @JonSkeet 问题已编辑! 【参考方案1】:

我知道,这是一个老问题,但 TokenValidationParameters 类有一个名为 ClockSkew 的属性,默认设置为 5 分钟。这可能是你的问题,因为它是我的。只需将此属性设置为例如 1 秒 - ClockSkew = TimeSpan.FromSeconds(1)

【讨论】:

【参考方案2】:

From the only source of this library got from google search 可以看到时间正在转换为世界时间(UTC)。

DateTime.Now.AddMinutes(15) 似乎是问题所在。 用Datetime.UtcNow.AddMinutes(15) 替换它可能会修复它

您的本地时区是 UTC+2:00 吗?

【讨论】:

刚刚再次测试,它停止工作。有什么想法吗? 只需阅读您提供的文档,它在代码中使用以下行作为过期时间: this[JwtRegisteredClaimNames.Exp] = EpochTime.GetIntDate(expires.Value.ToUniversalTime());也许这就是问题所在? "ToUniversalTime()" ? @perozzo - 嗨,我还没有时间看你的 cmets。我会在大约 5 小时后回到我的办公桌

以上是关于JwtSecurityToken 返回错误的过期时间的主要内容,如果未能解决你的问题,请参考以下文章

JwtSecurityToken 有最短过期时间吗?

无法加载类型“System.IdentityModel.Tokens.JwtSecurityToken”

是否将 AspNetUserClaims 中的添加声明添加到 JwtSecurityToken?

JwtSecurityTokenHandler 返回小写声明类型

Keycloak 返回已经过期的令牌

JwtSecurityToken 理解与异常