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