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

查看:1165
本文介绍了为什么我的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日星期三,当地时间下午5:14:10.

以下是Core库的一些记录的输出:

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'.

当然,此输出不能证明服务器在22:14:10到22:19:10之间接受令牌.如果我恰好在它过期后等待了5分钟然后尝试验证令牌,这是应该做的,但是您必须信服我.我在Postman中进行测试,并且每秒单击发送",直到返回401.

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

我正在使用的相关库:

<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" />

解决方案

那么,怎么了?是否有我不知道的内置5分钟缓冲区?发生了什么事?

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

您发现,

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天全站免登陆