Identity Server 3 refresh token expires before its expiration period set in the client configuration
Asked Answered
C

1

7

I am using Authorization Code flow for one of my Identity Server 3 clients and it is configured as follows:

ClientId = "tripgalleryauthcode",
ClientName = "Trip Gallery",
Flow = Flows.AuthorizationCode, 
AllowAccessToAllScopes = true,
RequireConsent = false,

// redirect = URI of our callback controller in the IOS application
RedirectUris = new List<string>
{
     "somecallbackuri"
},           

ClientSecrets = new List<Secret>()
{
    "somesecret"
},

// refresh token options
AccessTokenType = AccessTokenType.Jwt,
AccessTokenLifetime = 120,
RefreshTokenUsage = TokenUsage.OneTimeOnly,
RefreshTokenExpiration = TokenExpiration.Absolute,
AbsoluteRefreshTokenLifetime = 360,

As you can see, It is configured to expire the access token in 2 minutes and the refresh token in 6 minutes. I did this because I wanted to try to debug the problem in a smaller time frame instead of the one that I use in production : 15 days for refresh token, 1 hour for access token. We noticed that for some reason, refresh token issued today doesn't work tomorrow. That is why I decided to decrease the times and this is what happened:

  1. At 1:05 PM I made a refresh token request and received new refres and access tokens
  2. Now I expect my refresh token to expire at 1:11 PM
  3. At 1:10 PM I make call to the token end point using the refresh_token grant type trying to get new access and refresh tokens. What happens is that I get HTTP 400 error saying this is invalid_grant.

I have noticed even a bit more. What happens is that 2 minutes after the access token expiration I get the 400 error. It says refresh token is invalid.

This is the log from Identity Server.

w3wp.exe Information: 0 : 2016-11-23 10:56:15.802 +00:00 [Information] Start token request
w3wp.exe Information: 0 : 2016-11-23 10:56:15.802 +00:00 [Information] Client secret id found: "tripgalleryauthcode"
w3wp.exe Information: 0 : 2016-11-23 10:56:15.802 +00:00 [Information] Client validation success
w3wp.exe Information: 0 : 2016-11-23 10:56:15.802 +00:00 [Information] Start token request validation
w3wp.exe Information: 0 : 2016-11-23 10:56:15.802 +00:00 [Information] Start validation of refresh token request
w3wp.exe Warning: 0 : 2016-11-23 10:56:15.802 +00:00 [Warning] "Refresh token has expired"
 "{
  \"ClientId\": \"tripgalleryauthcode\",
  \"ClientName\": \"Trip Gallery\",
  \"GrantType\": \"refresh_token\",
  \"RefreshToken\": \"d12f50289e5cded13082de989a64ac01\",
  \"Raw\": {
    \"grant_type\": \"refresh_token\",
    \"refresh_token\": \"d12f50289e5cded13082de989a64ac01\"
  }
}"
w3wp.exe Information: 0 : 2016-11-23 10:56:15.818 +00:00 [Information] End token request
w3wp.exe Information: 0 : 2016-11-23 10:56:15.818 +00:00 [Information] Returning error: invalid_grant

I'd really like to know what causes that behavior and what causes my expiration token to expire before is deadline.

Contented answered 23/11, 2016 at 11:16 Comment(3)
We are facing the same problem. Did you found any solution for this? Need helpKrasnoff
Yes. As far as I remember, the issue was that I was storing the refresh tokens into the memory instead of in a DB or some other kind of persistent storage. I am running my identity server on a single service instance in Azure and its memory tends to clean itself up from time to time. So, my suggestion is to try to store the refresh tokens in a DB or file.Contented
Thanks, below linked also helped... linkKrasnoff
M
1

The reason why this happens is because there's a clock skew feature built into JWT that protects you from out of sync clocks. Without this you might run into problems where tokens are not valid yet.

The default value for this is 5 minutes - this affects the access_token as well as the refresh_token.

You can change this value with JwtBearerOptions.TokenValidationParameters.ClockSkew, in IdentityServer4.AccessTokenValidation.CombinedAuthenticationOptions

This behaviour is also specified in the official JWT Draft:

Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. Its value MUST be a number containing an IntDate value. This claim is OPTIONAL.

Microelement answered 25/4, 2017 at 8:34 Comment(1)
Please, check out this topic #43250412Contented

© 2022 - 2024 — McMap. All rights reserved.