SEE Below for code that solved this issue
I\'m trying to find the best and most efficient way to deal with a refresh token that has expired within A
The access token and refresh token are stored by ASP.NET core
I think it's important to note that the tokens are stored in the cookie that identifies the user to your application.
Now this is my opinion, but I don't think a custom middleware is the right place to refresh tokens. The reason for this is that if you successfully refresh the token, you'll need to replace the existing one and send it back to the browser, in the form of a new cookie that will replace the existing one.
This is why I think the most relevant place to do this is when the cookie is being read by ASP.NET Core. Every authentication mechanism exposes several events; for cookies, there's one called ValidatePrincipal which is called on every request after the cookie has been read and an identity has succesfully been deserialized from it.
public void ConfigureServices(ServiceCollection services)
{
services
.AddAuthentication()
.AddCookies(new CookieAuthenticationOptions
{
Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = context =>
{
// context.Principal gives you access to the logged-in user
// context.Properties.GetTokens() gives you access to all the tokens
return Task.CompletedTask;
}
}
});
}
The nice thing about this approach is that if you manage to renew the token and store it in the AuthenticationProperties, the context variable which is of type CookieValidatePrincipalContext, has a property called ShouldRenew. Setting that property to true instructs the middleware to issue a new cookie.
If you can't renew the token or you find the refresh token is expired and you want to prevent the user from going forward, that same class has a RejectPrincipal method which instructs the cookie middleware to treat the request as if it was aonymous.
The nice thing about this is that if your MVC app only allows authenticated users to access it, MVC will take care of issuing the HTTP 401 response which the authentication system will catch and turn into a Challenge and the user will be redirected back to the Identity Provider.
I have some code that shows how this would work over at the mderriey/TokenRenewal repository on GitHub. While the intent is different, it shows the mechanics of how to use these events.