2017-05-25 6 views
1

Ich benutze .net-Core mit IdentityServer 4. Ich habe eine Web-API und eine MVC-App, die auf sichere Endpunkte auf der API zugreifen. Es ist sehr ähnlich in Aufbau zum IdentityServer quickstart:Wie benutze ich 'refresh_token' in IdentityServer 4?

https://github.com/IdentityServer/IdentityServer4.Samples/tree/release/Quickstarts/6_AspNetIdentity

Ich finde, dass meine access_tokens auslaufen, und ich möchte wissen, wie refresh_tokens neu zu verhandeln.

Nehmen Sie den folgenden Code zum Beispiel (aus dem quickstart genommen here):

public async Task<IActionResult> CallApiUsingUserAccessToken() 
    { 
     var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token"); 

     var client = new HttpClient(); 
     client.SetBearerToken(accessToken); 
     var content = await client.GetStringAsync("http://localhost:5001/identity"); 

     ViewBag.Json = JArray.Parse(content).ToString(); 
     return View("json"); 
    } 

Wenn die access_token abgelaufen ist, wird es mit 401-Antwort fehl. Gibt es einen eingebauten Mechanismus für die Neuverhandlung der access_token unter Verwendung der refresh_token?

Antwort

2

Es gibt kein eingebautes System zum Aktualisieren der access_token. Sie können jedoch das Paket IdentityModel verwenden, um eine neue access_token mit einer refresh_token anzufordern. Die Client hat eine Eigenschaft AllowOfflineAccess, die Sie im IdentityServer auf true setzen müssen. Beachten Sie, dass dies nicht funktioniert für den impliziten/Client-Anmeldeinformationen fließen.

  • Immer die access_token vor auffrischen zu machen, indem Sie ihre Lebensdauer und fordern Sie eine neue access_token mit dem refresh_token (persönliche Präferenz), um den Anruf auf die geschützte Ressource
  • Überprüfen Sie, ob der aktuelle access_token etwa ist
  • abzulaufen warten Sie auf die API, um die 401-Anzeigenanfrage eine neue access_token mit dem refresh_token

Vor diesem Code zurückkehren Sie überprüfen können, die access_token Lebensdauer und/oder diesen Code in einem Service-wickeln, bevor Sie einen neuen 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); 

Entnommen und leicht modifiziert anfordern: Source

+0

Großen. Vielen Dank. Das funktioniert. –

Verwandte Themen