为什么我的 JWT 不记名身份验证在令牌显示 5 分钟后将令牌识别为过期? [英] Why is my JWT bearer authentication recognizing tokens as expired 5 minutes after the token says?

查看:23
本文介绍了为什么我的 JWT 不记名身份验证在令牌显示 5 分钟后将令牌识别为过期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 AspNet.Security.OpenIdConnect.Server 发布 JWT 令牌并将 AuthorizationCodeLifetime 设置为 30 秒以进行测试.这是我用来设置选项的代码片段

 options.TokenEndpointPath = "/api/token";options.AllowInsecureHttp = true;options.AccessTokenHandler = new JwtSecurityTokenHandler();options.SigningCredentials.Add(new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256));options.AccessTokenLifetime = TimeSpan.FromSeconds(30);options.AuthorizationCodeLifetime = TimeSpan.FromSeconds(30);

返回的令牌包含:

 "expires_in": 30,

并且反序列化的令牌包含以下声明:

 "nbf": 1476915220,exp":1476915250,iat":1476915220,

如您所见,exp(过期时间)是在 iat(发布时间)之后 30 秒.然而,令牌在过期 5 分钟后才会触发 401 Unauthorized.如果我们将 exp 编号插入 http://www.epochconverter.com/ 然后我们会看到这个评估为 2016 年 10 月 19 日星期三 22:14:10 GMT,即我当地时间下午 5:14:10.

这是核心库的一些记录输出:

Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException:IDX10223:生命周期验证失败.令牌已过期.ValidTo: '10/19/2016 22:14:10'当前时间:'10/19/2016 22:19:10'.在 Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters)在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken securityToken, TokenValidationParameters validationParameters)在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken&validatedToken)在 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext()信息:Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[7]Bearer 未经过身份验证.失败消息:IDX10223:生命周期验证失败.令牌已过期.ValidTo: '10/19/2016 22:14:10'当前时间:'10/19/2016 22:19:10'.

当然,这个输出并不能证明服务器在 22:14:10 到 22:19:10 之间接受了令牌.如果我碰巧在它过期后等待了 5 分钟,然后尝试验证令牌,它就会这样做,但你必须相信我的话.我在 Postman 中进行测试,每秒点击一次发送",直到返回 401.

所以,怎么了?是否有一些我不知道的内置 5 分钟缓冲区?有趣的是,AccessTokenLifetime 的默认值是 5 分钟,但令牌肯定反映了我已将其更改为 30 秒.怎么回事?

我正在使用的相关库:

<package id="AspNet.Security.OpenIdConnect.Server" version="1.0.0-beta6-final" targetFramework="net452"/><package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="1.0.0" targetFramework="net452"/>

解决方案

所以,怎么了?是否有一些我不知道的内置 5 分钟缓冲区?怎么回事?

您所说的缓冲区"实际上是 JWT 承载中间件(由 Microsoft 开发)提供的一项内置功能,称为时钟偏差",旨在​​减轻网络农场中时钟不同步的影响.

如您所见,默认值设置为 5 分钟,但可以通过 JwtBearerOptions.CCode>S

I'm using AspNet.Security.OpenIdConnect.Server to issue JWT tokens and have the AuthorizationCodeLifetime set to 30 seconds for testing. Here is the snippet of code I'm using to set the options

        options.TokenEndpointPath = "/api/token";
        options.AllowInsecureHttp = true;
        options.AccessTokenHandler = new JwtSecurityTokenHandler();
        options.SigningCredentials.Add(new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256));
        options.AccessTokenLifetime = TimeSpan.FromSeconds(30);
        options.AuthorizationCodeLifetime = TimeSpan.FromSeconds(30);

The returned token contains:

  "expires_in": 30,

and the deserialized token contains the following claims:

 "nbf": 1476915220,
 "exp": 1476915250,
 "iat": 1476915220,

As you can see, the exp (expire time) is 30 seconds after the iat (issue time). Yet, the token isn't triggering an 401 Unauthorized until 5 minutes after it expires. If we plug the exp number in to http://www.epochconverter.com/ then we will see that this evaluates to Wed, 19 Oct 2016 22:14:10 GMT which is 5:14:10 PM in my local time.

Here is some logged output from the Core library :

Microsoft.IdentityModel.Tokens.SecurityTokenExpiredException: IDX10223: Lifetime validation failed. The token is expired.
ValidTo: '10/19/2016 22:14:10'
Current time: '10/19/2016 22:19:10'.
   at Microsoft.IdentityModel.Tokens.Validators.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, SecurityToken securityToken, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateLifetime(Nullable`1 notBefore, Nullable`1 expires, JwtSecurityToken securityToken, TokenValidationParameters validationParameters)
   at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.<HandleAuthenticateAsync>d__1.MoveNext()
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware[7]
      Bearer was not authenticated. Failure message: IDX10223: Lifetime validation failed. The token is expired.
ValidTo: '10/19/2016 22:14:10'
Current time: '10/19/2016 22:19:10'.

Of course, this output doesn't prove that the server was accepting the token between 22:14:10 and 22:19:10. This is what it would have done had I happen to have waited 5 minutes after it was expired and then tried to validate the token, but you'll have to take my word for it. I was testing in Postman and was clicking "Send" every second until it returned a 401.

So, what's up? Is there some 5 minute buffer built in that I'm not aware of? Interestingly, the default value for the AccessTokenLifetime is 5 minutes, but the token is definitely reflecting that I've changed it to 30 seconds. What's going on?

Relevant libraries I'm using:

<package id="AspNet.Security.OpenIdConnect.Extensions" version="1.0.0-beta6-final" targetFramework="net452" />
<package id="AspNet.Security.OpenIdConnect.Server" version="1.0.0-beta6-final" targetFramework="net452" />
<package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="1.0.0" targetFramework="net452" />

解决方案

So, what's up? Is there some 5 minute buffer built in that I'm not aware of? What's going on?

What you call "buffer" is actually a built-in feature offered by the JWT bearer middleware (developed by Microsoft) which is known as "clock skew" and was designed to mitigate the effects of clock desynchronization in web farms.

As you figured out, the default value is set to 5 minutes, but it can be changed via JwtBearerOptions.TokenValidationParameters.ClockSkew.

这篇关于为什么我的 JWT 不记名身份验证在令牌显示 5 分钟后将令牌识别为过期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆