Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IdentityServer4 Refresh Token: How to determine expiration time?

I am working with the Identity Server 4 sample code. In particular, for the client I am using the sample MVC Client with the Hybrid flow: https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Clients/src/MvcHybrid

And for the server I am using Identity Server with in-memory clients (no Entity Framework, and no ASP.Net Identity): https://github.com/IdentityServer/IdentityServer4/tree/master/samples/Quickstarts

Both client and server have pretty much vanilla, out-of-the-box configuration.

I am trying to understand how refresh tokens expire and how a native app can pro-actively determine the expiration time (before it gets rejected by an API). My understanding is that the default expiration for refresh tokens is long:

http://docs.identityserver.io/en/latest/topics/refresh_tokens.html:

Maximum lifetime of a refresh token in seconds. Defaults to 2592000 seconds / 30 days

However, when the sample code requests a refresh token, I do not get the expected expiration time. Here is the sample code:

var disco = await _discoveryCache.GetAsync();
if (disco.IsError) throw new Exception(disco.Error);

var rt = await HttpContext.GetTokenAsync("refresh_token");
var tokenClient = _httpClientFactory.CreateClient();

var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
    Address = disco.TokenEndpoint,

    ClientId = "mvc.hybrid",
    ClientSecret = "secret",
    RefreshToken = rt
});

tokenResult.ExpiresIn is 3600 seconds, which is actually the expiration of an access token. I was expecting that to be 2592000 seconds. So question #1 is: Why is this the case?

But more importantly, I know that the expiration for the refresh token is in fact the default 30 days when I use SQL Server as the data store. There is a table PersistedGrants that contains the refresh tokens, and the expiration is clearly 30 days from the issue date. So question #2 is: How can an app programmatically determine the expiration date of the refresh token it received?

I've tried to parse the RefreshToken itself, but it is not really a full JWT, so this throws an error:

var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessTokenResponse.RefreshToken);
var diff = jwt.ValidTo - jwt.ValidFrom;

I've also searched through the IdentityServer4 unit / integration tests and cannot find an example of introspecting a refresh token.

Presumably that information either needs to be somewhere in the initial token response, or there needs to be an endpoint built into Identity Server. But I can't find either of these things.

like image 934
anon Avatar asked Dec 12 '19 22:12

anon


People also ask

How do I check my refresh token expiry?

If you look in the dashboard application settings, you can see the Refresh Token expiration time. By default, it is 720 hours (2592000 seconds). Since the error message says inavlid_grant , it may be possible that the application is not configured to accept Refresh Token grants.

How do you get expiry time from tokens?

Go to Dashboard > Applications > APIs and click the name of the API to view. Locate the Token Expiration (Seconds) field, and enter the appropriate access token lifetime (in seconds) for the API. Default value is 86,400 seconds (24 hours). Maximum value is 2,592,000 seconds (30 days).

What is by default expiration time of refresh token?

By default, access tokens are valid for 60 days and programmatic refresh tokens are valid for a year.

Why do we refresh the access token when it expires?

This action will enable us to silently refresh the access token when it is close to expiry. Also, it will provide a better user experience because the user doesn’t have to manually log in every time the access token expires in our application.

What are refresh tokens in identityserver 4?

IdentityServer4 – Part 4 – Refresh Tokens By Rami Hamati | IdentityServer | 0 comment | 20 October, 2019 | 1 What are refresh tokens? Refresh tokens are means to grant an application access to a protected resource when the access token expires.

What are the benefits of sliding expiration for refresh tokens?

With sliding expiration you can set a shorter refresh token lifetime. Because each time an access token is requested, a new refresh token is issued. Extending the lifetime and invalidating the used refresh token. The user can access the resource without having to login again as long as the refresh token is valid.

How can I automate the process of access token renewal?

In order to automate the process of access token renewal you can use the refresh token. This is a powerful token, since it can be used to request an access token without user interaction. The refresh token should be long lived (at least longer than the access token). Once the refresh token expires, the user has to login again.


1 Answers

Ok, so the answer is that there is no data in the access_token response that indicates the expiration time of the refresh_token. Additionally, there is no endpoint that can be used to check the expiration.

The OAuth spec does not say anything about this, so I did not want to alter the access_token response. I wound up making my own endpoint that returns the expiration time if needed. Here is my controller action, if anyone needs a starting point:

private readonly IRefreshTokenStore _refreshTokenStore; // inject this into your controller

...

[Route("[controller]/GetRefreshTokenExpiration")]
[Authorize(...YOUR SCOPE...)]
public async Task<IActionResult> GetRefreshTokenExpiration(string refreshTokenKey)
{
    var refreshToken = await this._refreshTokenStore.GetRefreshTokenAsync(refreshTokenKey);
    if (refreshToken == null)
    {
        return NotFound(new { message = "Refresh token not found" });
    }
    return Ok(new {
        message = "Refresh token found",
        lifetime_seconds = refreshToken.Lifetime
    });
}
like image 67
anon Avatar answered Oct 10 '22 09:10

anon