DEV Community

loading...
Cover image for Setting up an Authorization Server with OpenIddict - Part VI - Refresh tokens

Setting up an Authorization Server with OpenIddict - Part VI - Refresh tokens

robinvanderknaap profile image Robin van der Knaap ・2 min read

This article is part of a series called Setting up an Authorization Server with OpenIddict. The articles in this series will guide you through the process of setting up an OAuth2 + OpenID Connect authorization server on the the ASPNET Core platform using OpenIddict.

GitHub logo robinvanderknaap / authorization-server-openiddict

Authorization Server implemented with OpenIddict.


Access tokens typically have a short lifetime for security reasons. In this part we will enable the usage of refresh tokens. A refresh token allows an application to obtain a new access token without prompting the user.

Enable refresh tokens

First we need to enable the refresh token flow in Startup.cs:

options
    .AllowAuthorizationCodeFlow()
        .RequireProofKeyForCodeExchange()
    .AllowClientCredentialsFlow()
    .AllowRefreshTokenFlow();
Enter fullscreen mode Exit fullscreen mode

In the token endpoint in the AuthorizationController we need to handle refresh token requests, just like we handled client credentials requests, and requests to exchange authorization codes for access tokens:

[HttpPost("~/connect/token")]
public async Task<IActionResult> Exchange()
{
    ...

    else if (request.IsAuthorizationCodeGrantType())
    {
        ...
    }

    else if (request.IsRefreshTokenGrantType())
    {
        // Retrieve the claims principal stored in the refresh token.
        claimsPrincipal = (await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)).Principal;
    }

    ...
}
Enter fullscreen mode Exit fullscreen mode

Basically, we only need to retrieve the ClaimsPrincipal from the refresh token, and sign in again, which will return a new access token.

Finally, we need to allow the client to use refresh tokens:

Permissions =
{
    OpenIddictConstants.Permissions.Endpoints.Authorization,
    OpenIddictConstants.Permissions.Endpoints.Token,

    OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
    OpenIddictConstants.Permissions.GrantTypes.ClientCredentials,
    OpenIddictConstants.Permissions.GrantTypes.RefreshToken,

    OpenIddictConstants.Permissions.Prefixes.Scope + "api",

    OpenIddictConstants.Permissions.ResponseTypes.Code
}
Enter fullscreen mode Exit fullscreen mode

If a client wants to use refresh tokens, it needs to request the offline_access scope. Just like we requested the openid scope for identity tokens. Now, if we request a new access token with Postman, we will receive a refresh token together with the access token.

After that, we can use the refresh token to request a new access token with Postman. Send a POST request to /connect/token with a body containing the client credentials, grant type and of course the refresh token.

Alt Text

In the response you will find a new access token and also a new refresh token. So, refresh tokens are automatically rotated, which is more secure than reusing the same refresh token.

Discussion (2)

pic
Editor guide
Collapse
capesean profile image
Sean Walsh

Thanks Robin. I needed to add the following lines, to include the refresh token in the jwt, not sure if it's necessary in your codebase though:

github.com/openiddict/openiddict-s...

Collapse
capesean profile image
Sean Walsh

Ah, never mind. I see you have it there:
github.com/robinvanderknaap/author...