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.
- Part I: Introduction
- Part II: Create ASPNET project
- Part III: Client Credentials Flow
- Part IV: Authorization Code Flow
- Part V: OpenID Connect
- Part VI: Refresh tokens
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();
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;
}
...
}
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
}
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.
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 (5)
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...
Ah, never mind. I see you have it there:
github.com/robinvanderknaap/author...
embassador, with these rocher your spoil us
Great series! Thanks!
Would you make another article on how to leverage custom grants?
How to implement the logout flow, where I need to return a redirect_uri to the client, and also invalidate the id_token?