I am storing my access and refresh tokens inside the HttpContext via HttpContext.StoreTokens(). I can retrieve these in my App.razor and pass them to the rest of the application from there. This works fine, but I am struggling to figure out a good way to perform token refreshes. I could just refresh them right in App.razor (after retrieving them and checking for validity), but that would only work when the user refreshes the page. Ideally every API request would automatically perform a token refresh when needed. This is tricky though since HttpContext is not accessible at this point.
My current workaround is to create an extra controller that performs the refresh and updates the HttpContext. This controller is called via HttpClient that is configured to pass cookie headers. This gives me access to the proper HttpContext, but updating the tokens does not seem to work:
[Route("/token/refresh")][Authorize]public async Task<ActionResult<TokenRefreshResponse>> TokenRefresh( [FromQuery(Name = "refresh_token")] string refreshToken){ //Perform refresh var authResult = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme); Debug.Assert(authResult.Succeeded); authResult.Properties.UpdateTokenValue("AccessToken", newAccessToken); authResult.Properties.UpdateTokenValue("RefreshToken", newRefreshToken);}This is how the HttpClient is configured:
services.AddHeaderPropagation(options => options.Headers.Add("Cookie"));services.AddHttpClient(HttpClients.WebUi, client => client.BaseAddress = "localhost:443") .AddHeaderPropagation();This is how the endpoint is called:
public async Task RefreshTokenAsync() { var client = httpClientFactory.CreateClient(HttpClients.WebUi); var response = await client.GetAsync($"token/refresh?refresh_token={RefreshToken}"); //...}Despite it not working correctly it really feels like a hack to call myself just to get hold of an HttpContext. Is there any better way of handling this? Maybe I should just not use HttpContext at all and create a custom AuthorizationStateProvider instead that stores tokens inside ProtectedLocalStorage?