There is not a build in system to refresh the access_token
. However you can use the IdentityModel
package to request a new access_token
with a refresh_token
.
The Client
has a property AllowOfflineAccess
which you should set to true in the IdentityServer. Note that this does not work for the implicit/client credentials flow.
- Always refresh the access_token prior to making the call to the protected resource
- Check if the current
access_token
is about to expire by checking its lifetime and request a new access_token
with the refresh_token
(personal preference)
- Wait for the API to return the 401 ad request a new
access_token
with the refresh_token
Prior to this code you can check the access_token
lifetime and/or wrap this code in a service before you request a new access_token
var discoveryResponse = await DiscoveryClient.GetAsync("IdentityServer url");
if (discoveryResponse.IsError)
{
throw new Exception(discoveryResponse.Error);
}
var tokenClient = new TokenClient(discoveryResponse.TokenEndpoint, "ClientId", "ClientSecret");
// This will request a new access_token and a new refresh token.
var tokenResponse = await tokenClient.RequestRefreshTokenAsync(await httpContext.Authentication.GetTokenAsync("refresh_token"));
if (tokenResponse.IsError)
{
// Handle error.
}
var oldIdToken = await httpContext.Authentication.GetTokenAsync("id_token");
var tokens = new List<AuthenticationToken>
{
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.IdToken,
Value = oldIdToken
},
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.AccessToken,
Value = tokenResult.AccessToken
},
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.RefreshToken,
Value = tokenResult.RefreshToken
}
};
var expiresAt = DateTime.UtcNow.AddSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken
{
Name = "expires_at",
Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
});
// Sign in the user with a new refresh_token and new access_token.
var info = await httpContext.Authentication.GetAuthenticateInfoAsync("Cookies");
info.Properties.StoreTokens(tokens);
await httpContext.Authentication.SignInAsync("Cookies", info.Principal, info.Properties);
Taken from and slightly modified: Source
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…