2017-03-27 1 views
3

Ich habe als ASP.net Core MVC-Site, die OpenId verbindet, um mit einer anderen ASP.net Core-Website zu authentifizieren, die IdentityServer4 verwendet, die eine andere IdentityServer4-Site als Identity-Provider verwendet .Identityserver4/OpenId Connect, Hybrid-Modus, Token Refresh Fails

Auf dem Client gibt es sehr wenige Seiten, die theoretisch nur mit AJAX-Calls lange benutzt werden können. Ich möchte die Seite aktualisieren, um den Zugriffstoken zu aktualisieren, damit der Benutzer nicht gezwungen wird, sich anzumelden, sagen wir am nächsten Tag.

Ich habe einen Timer eingerichtet, der eine WebAPI-Methode auf der MVC-Site aufruft, die das Token aktualisiert.

Es funktioniert mit den ersten zwei Aktualisierungen, aber immer mit der dritten.

Die Methode gibt eine JWT zurück, die für externe API-Aufrufe verwendet werden soll. Ich kann diese Updates beim ersten Aufruf wie erwartet sehen und erhält einen neuen Ablaufzeitstempel.

Im dritten Aufruf schlägt tokenClient.RequestRefreshTokenAsync fehl, da refreshToken null ist.

public async Task<IActionResult> RefreshToken() 
    { 
     var disco = await DiscoveryClient.GetAsync(_authenticationOptions.Value.Authority); 

     if (disco.IsError) 
      return BadRequest(disco.Error); 

     var tokenClient = new TokenClient(disco.TokenEndpoint, _authenticationOptions.Value.ClientId, _authenticationOptions.Value.ClientSecret); 
     var refreshToken = await HttpContext.Authentication.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken); 
     var tokenResult = await tokenClient.RequestRefreshTokenAsync(refreshToken); 

     if (tokenResult.IsError) 
      return BadRequest(disco.Error); 

     var old_id_token = await HttpContext.Authentication.GetTokenAsync(OpenIdConnectParameterNames.IdToken); 
     var new_access_token = tokenResult.AccessToken; 
     var new_refresh_token = tokenResult.RefreshToken; 

     var tokens = new List<AuthenticationToken>(); 
     tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = old_id_token }); 
     tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.AccessToken, Value = new_access_token }); 
     tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.RefreshToken, Value = new_refresh_token }); 

     var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn); 
     tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) }); 

     var info = await HttpContext.Authentication.GetAuthenticateInfoAsync("Cookies"); 
     info.Properties.StoreTokens(tokens); 

     await HttpContext.Authentication.SignOutAsync("Cookies"); 
     await HttpContext.Authentication.SignInAsync("Cookies", info.Principal, info.Properties); 

     return Ok(HttpContext.Authentication.GetTokenAsync("access_token").Result); 
    } 

ich sehen kann, dass Chrome in der Konsole wird benachrichtigt, dass ein Set-Cookie-Header ignoriert wird, weil es 4kb übersteigt.

Irgendwelche Tipps?

+0

4KB ist ein Limit für Cookies in ** den meisten ** Browsern: http://browsercookielimits.squawky.net/ Wenn Sie die Nutzlast verkleinern oder in mehr als einen Cookie aufteilen können, könnten sie dann gespeichert werden. –

+0

Gemäß der Spezifikation gibt es _Empfehlungen_, aber der Link, den ich früher zur Verfügung gestellt habe, ist ein praktischeres Limit: http://www.ietf.org/rfc/rfc2965.txt siehe Abschnitt 5.3 über Grenzen. –

+0

Meine Vermutung ist, dass, weil es keine 'try' /' catch' oder irgendeine 'null' Prüfung gibt, was Sie sehen, ist die Stack-Trace-Seite in HTML als Reaktion auf diese Aktion. –

Antwort

0

Verstanden.

Die Clients IdentityToken abgelaufen, und da diese API-Methode wurde nicht durch [Autorisieren] -Attribut geschützt, es nicht erneuert + das Skript geändert, um einen iframe anstelle von AJAX-Aufrufe zu verwenden!

Gehäuse geschlossen.