2015-12-10 18 views
9

Stiamo provando a configurare Identity Server 3 nel modo corretto. L'autenticazione funziona correttamente e riusciamo a recuperare il token di aggiornamento.IdentityServer 3 aggiorna utente con token di aggiornamento

L'applicazione client utilizza Angolare.

Ora, quando acces_token termina le chiamate al resto, api non riesce (siamo riusciti a farlo restituire 401) ma ci stiamo chiedendo come autenticare nuovamente l'utente.

Nei nostri test, qualsiasi chiamata api effettuata da Javascript non riesce (401) ma non appena la pagina viene aggiornata l'intero meccanismo si avvia. Vediamo che siamo reindirizzati al server di identità ma non mostra fino alla pagina di accesso, verremo reindirizzati all'applicazione client con nuovi token apparentemente.

Quello che mi piacerebbe fare è aggiornare il token di accesso senza dover forzare l'utente ad aggiornare la pagina.

Ciò che non sono sicuro è di chi è la responsabilità? È l'applicazione client (sito Web) o l'applicazione angolare? In altre parole, se l'applicazione lo gestisce in modo trasparente per Angular o dovrebbe fare qualcosa angolare quando riceve un 401, nel qual caso, non sono molto sicuro di come le informazioni torneranno all'applicazione web.

Qualsiasi indizio?

Informazioni aggiuntive: Stiamo usando OpenID Connect

+0

Ho lo stesso problema, suppongo che il Controller che visualizza l'applicazione e il/i Controller chiamato dal client (ajax) utilizzino un diverso tipo di Autenticazione, quindi 'app.UseOpenIdConnectAuthentication()' solo per il primo tipo, e per il secondo ... non lo so ma sto cercando di capire – Naigel

+0

Sto iniziando a pensare che dovrei effettivamente spingere l'access_token e refresh_token verso il basso per l'applicazione js ma questo è un po 'brutto IMHO. Cercando di trovare un buon modo per farlo. Ho effettivamente visto come MS lo sta facendo nel portale di Azure e questo è decisamente sgradevole ... –

+0

Il "secondo tipo" di autenticazione necessario dovrebbe essere qualcosa con il token al portatore, quindi "app.UseOpenIdConnectAuthentication' per le viste MVC e l'app .UseIdentityServerBearerTokenAuthentication' (o un altro portatore) per API. Nel frattempo la mia soluzione alternativa è l'estensione dei token nelle configurazioni client sul server Identity --- 'AccessTokenLifetime = 3600 * 12, // estensione da predefinito 3600 sec/1 ora a 12 ore' --- ' IdentityTokenLifetime = 300 * 20 * 12, // estendere da predefinito 300 sec/5 min a 12 ore – Naigel

risposta

4

ho ottenuto che funziona!

Come ho detto nei commenti, ho utilizzato l'articolo this. Lo scrittore fa riferimento a uno very nice lib che sto usando pure.

Fatti:

  1. Identity Server 3 richiede il segreto cliente al momento l'accesso token di aggiornamento
  2. non si dovrebbe conservare il refresh_token o client_secret sull'applicazione javascript in quanto sono considerati non sicuri (vedi the article)

così ho scelto di inviare il refresh_token come en cookie crittografato Sith questa classe (che si trova di ST BTW, proprio non riesce a trovare il collegamento più, mi spiace ...)

public static class StringEncryptor 
{ 
    public static string Encrypt(string plaintextValue) 
    { 
     var plaintextBytes = plaintextValue.Select(c => (byte) c).ToArray(); 
     var encryptedBytes = MachineKey.Protect(plaintextBytes); 
     return Convert.ToBase64String(encryptedBytes); 
    } 

    public static string Decrypt(string encryptedValue) 
    { 
     try 
     { 
      var encryptedBytes = Convert.FromBase64String(encryptedValue); 
      var decryptedBytes = MachineKey.Unprotect(encryptedBytes); 
      return new string(decryptedBytes.Select(b => (char)b).ToArray()); 
     } 
     catch 
     { 
      return null; 
     } 
    } 
} 

L'applicazione javascript sta ottenendo il valore dal cookie. Elimina quindi il cookie per evitare che quella cosa venga inviata più e più volte, è inutile.

Quando access_token non è più valido, invio una richiesta http al server delle applicazioni con il refresh_token crittografato. Questa è una chiamata anonima.

Il server contatta il server di identità e ottiene un nuovo token di accesso che viene rinviato a Javascript. Il awesome library ha messo in coda tutte le altre richieste, quindi quando torno con il mio nuovo token, posso dire di continuare con authService.loginConfirmed();.

L'aggiornamento è in realtà abbastanza semplice in quanto tutto ciò che dovete fare è utilizzare TokenClient da IdentityServer3.codice del metodo completi:

[HttpPost] 
    [AllowAnonymous] 
    public async Task<JsonResult> RefreshToken(string refreshToken) 
    { 
     var tokenClient = new TokenClient(IdentityServerConstants.IdentityServerUrl + "/connect/token", "my-application-id", "my-application-secret"); 
     var response = await tokenClient.RequestRefreshTokenAsync(StringEncryptor.Decrypt(refreshToken)); 

     return Json(new {response.AccessToken}); 
    } 

I commenti sono benvenuti, questo è probabilmente il modo migliore per farlo.

+0

Bello ma c'è una cosa che non capisco. Come rinnovate in modo efficace le vostre credenziali una volta ottenuto il 'response.AccessToken'? Fondamentalmente chiamo la funzione 'RefreshToken' quando ottengo un' response.status == 401' da una delle mie chiamate ajax e ottengo il nuovo 'AccessToken' sul client ... e poi? – Naigel

+0

Pensavo di poter rinnovare le credenziali direttamente nella funzione di controllo "RefreshToken", ma lì sono un utente anonimo. C'è un qualche tipo di codice da autenticare di nuovo immediatamente, qualcosa come 'Request.GetOwinContext(). Authentication.UnknowFunctionToRenewMyAuth (response.AccessToken)' – Naigel

+0

Non sono sicuro di aver capito la domanda ... il metodo RequestRefreshTokenAsync è lì solo per rinnovare l'accesso gettone. Cosa stai cercando di ottenere con le credenziali? –

0

Per riferimento futuro: l'utilizzo di token di aggiornamento in un'applicazione angolare (o altra JS) non è il modo corretto in quanto un token di aggiornamento è troppo sensibile per l'archiviazione nel browser. È necessario utilizzare il rinnovo silenzioso basato sul cookie identityserver per ottenere un nuovo token di accesso. Vedi anche la libreria javascript oidc-client-js, in quanto può gestire il rinnovo silenzioso per te.

Problemi correlati