I've followed the Quickstart in the documentation page and have a working configuration of three services (IdentityServer, one Api service, one ASPNET MVC application) using IdentityServer for authentication.
Everything works perfectly (login, login, authorization, etc.) until after 1 hour when the access_token expires. At this point, the MVC application starts to receive (correctly) a 401 from the API service (since the token is expired). At that point, I know I should use the refresh_token to get a new access_token.
I was looking for a mechanism that automatically refreshed the access_token and stumbled upon this: https://github.com/mderriey/TokenRenewal/blob/master/src/MvcClient/Startup.cs (from this answer). I tried to use that but it didn't work (the TokenEndpointResponse
was null even though the authentication was successful).
I understand how to use a refresh_token
to get a new access_token
, but after I have it, how would I go inserting it back into the cookie so that future request have access to the new tokens?
I made middleware that makes the job automatically, when more than half of the life of the token passed. So you didn't need to call any method or apply any filter. Just insert this into Startup.cs and whole application is covered:
UseAutomaticSilentRenew - Renews access and refresh tokens
UseAccessTokenLifetime - Signs out user if access token is expired. Put this second to make it work only if the UseAutomaticSilentRenew failed to obtain new access token earlier.
Implementation:
Note: I didn't set cookie expiration time because in our case it depends on refresh token lifetime witch is not provided by identity server. If I aligned the expiration of the cookie with the expiration of the access token I would't be able to refresh access token after its expiration.
Oh, and another thing. UseAccessTokenLifetime clears the cookie but doesn't signs out the user. Sign out occurs after you reload the page. Didn't find a way to fix it.
The link you provided to https://github.com/mderriey/TokenRenewal/blob/master/src/MvcClient/Startup.cs really helped me!
The gotcha was in the AddOpenIdConnect section. The event you want is not the OnTokenValidated event. You should use the OnTokenResponseReceived event. It's at that point you'll have a proper access_token and refresh_token to add to the cookie.
As an option to RenewTokens method from MVC Client example, I made one filter that makes the job automatically, when the token is about 10 minutes or less to expire.
Usage:
First, be sure to use IdentityModel library (nuget it). Second, since Auth 2.0 is out there are some breaking changes and HttpContext.Authentication used in Rafaels solution is now obsolete. Here are the changes which should be made to get it up and running as a filter again
should become:
should become:
should become
should become
should become
And this is the a whole code:
Usаge is the same as Rafael showed.
The McvHybrid sample has a good example for getting the new
access_token
andrefresh_token
back into the principal. Here's a link to the github file with the code, which is located inRenewTokens()
as shown below.