oauth-2.0 flow - Gestione dei token di accesso scaduti nella concessione implicita di OAuth2




authentication authorization (3)

Le specifiche di OAuth2 indicano che un server di autorizzazione non deve emettere un token di aggiornamento quando si utilizza la concessione implicita. Nel nostro caso d'uso proteggiamo un'API RESTful con OAuth2 e usiamo un'applicazione Javascript in una pagina singola come client per questa API. Poiché sarebbe molto difficile reindirizzare al server di autorizzazione dopo che un token di accesso è scaduto, stiamo cercando un modo migliore per ottenere un nuovo token valido. Potrei pensare a due diversi approcci e mi chiedo quale potrebbe essere meglio:

  1. Usa un iframe nascosto per Rerequest un token di accesso valido. Per questo è necessario includere un parametro come "prompt = none" che indica al provider OAuth di non sfidare l'autenticazione, né di visualizzare una pagina di autorizzazione. Se l'utente è autenticato e ha autorizzato l'applicazione, il server invierà un token di accesso nei parametri # url. Se una delle condizioni precedenti non è soddisfatta, verrà reindirizzata con un errore come # error = authentication% 20lost. Con questo comportamento possiamo usare i token di accesso di breve durata anche con un flusso implicito.

  2. Potremmo utilizzare un ambito aggiuntivo (ad esempio offline) che indica al server di distribuire un token di aggiornamento. Anche se la specifica originale dice che il flusso implicito non emette token di aggiornamento (che è corretto se il client utilizza solo OAuth per una prima autorizzazione), sei libero di definire i tuoi ambiti per la tua particolare applicazione. Si dovrebbe considerare di consentire questo ambito solo a clienti noti.

Entrambi gli approcci sono molto simili a quelli di OpenID Connect. Sfortunatamente al momento non ci sono molte implementazioni di OpenID Connect. Quindi il primo passo sarebbe estendere il server OAuth2 fino a quando l'OIC sarà più popolare.

Quindi quale approccio dovrebbe essere preferito?

EDIT : l'endpoint del token richiede l'autenticazione del client, che è possibile solo per i client riservati come le applicazioni lato server. Con il secondo approccio, sarebbe possibile consentire all'API RESTful nel nostro caso il provider di risorse di aggiornare il token e inviarlo al client. Penso che questo sarebbe un rischio per la sicurezza. Quindi probabilmente abbiamo solo un approccio valido.


Answers

Dal sito Web OAuth0 :

Se è necessario autenticare gli utenti senza una pagina di accesso (ad esempio, quando l'utente ha già effettuato l'accesso tramite lo scenario SSO) o ottenere un nuovo access_token (quindi simulare l'aggiornamento di un token scaduto), è possibile utilizzare l'autenticazione silenziosa.

Per quanto riguarda l' autenticazione silenziosa :

Tuttavia, il reindirizzamento degli utenti dall'applicazione è solitamente considerato di disturbo e dovrebbe essere evitato, dal punto di vista dell'UX. L'autenticazione silenziosa consente di eseguire un flusso di autenticazione in cui Auth0 risponderà solo con reindirizzamenti e mai con una pagina di accesso.

Ciò ti consentirà di accedere nuovamente all'utente utilizzando un token SSO, senza doverlo richiamare nuovamente per le credenziali.


Sto cercando di ottenere la stessa identica cosa al momento.

Ho effettivamente implementato l'approccio iframe nascosto e poi ho capito che devi stare molto attento con iframe. Qualsiasi sito Web dannoso può contenere l'iframe e ottenere facilmente il token di accesso se non si specifica X-Frame-Options .

L'approccio migliore per il token di aggiornamento dovrebbe essere la concessione della password, come specificato dalla specifica. (Volevo che i miei utenti effettuassero il login con il loro account Facebook e il flusso implicito fosse più facile da sviluppare. Non ho ancora capito come farlo con la concessione di password.)

Anche il secondo approccio mi è venuto in mente e mi sembra molto più sicuro del primo, dal momento che di solito puoi fidarti dell'https e del browser per mantenere segreti i token.

modificare

Mi sono reso conto, anche con X-Frame-Options maggior parte dei browser non può impedire i reindirizzamenti, perché questa intestazione è allegata al corpo della risposta e l'URL reindirizzato verrà esposto, quindi i token di accesso verranno esposti.

Aggiornamento Sembra che il frammento di hash sia protetto dal browser quando si accede dalla pagina padre all'interno di un dominio diverso. Quindi presumo che #access_token sia sicuro. Colpa mia. Proprio come una pagina di richiamata promemoria deve memorizzare il token di accesso a sé stante, anziché (la mia intenzione originale) delegandolo alla pagina padre come window.parent.storeAccessToken(hash); che ovviamente è una cosa stupida da fare.


tl; dr: Questo è tutto per ragioni di sicurezza.

OAuth 2.0 voleva soddisfare questi due criteri:

  1. Si desidera consentire agli sviluppatori di utilizzare URI di reindirizzamento non HTTPS poiché non tutti gli sviluppatori dispongono di un server abilitato SSL e, in caso contrario, non sono sempre configurati correttamente (certificati SSL autofirmati e non firmati, orologio del server sincronizzato ...).
  2. Non vuoi che gli hacker siano in grado di rubare i token di accesso / aggiornamento intercettando le richieste.

Dettagli di seguito:

Il flusso implicito è possibile solo in un ambiente browser per motivi di sicurezza:

Nel flusso implicito il token di accesso viene passato direttamente come un frammento hash (non come parametro URL). Una cosa importante del frammento hash è che, una volta seguito un collegamento contenente un frammento hash, solo il browser è a conoscenza del frammento hash. I browser passeranno il frammento di hash direttamente alla pagina Web di destinazione (l'URI di reindirizzamento / la pagina Web del client). Il frammento di hash ha le seguenti proprietà:

  • Non fanno parte della richiesta HTTP quindi non possono essere letti dai server e per questo non possono essere intercettati da server / router intermedi (questo è importante).
  • Esiste solo sul browser - lato client - quindi l'unico modo per leggere il frammento hash è usare JavaScript che viene eseguito sulla pagina.

Ciò rende possibile il passaggio di un token di accesso direttamente al client senza il rischio che venga intercettato da un server intermedio. Questo ha l'avvertenza di essere solo lato client possibile e necessita di javascript che eseguono il lato client per utilizzare il token di accesso.

Nel flusso del codice di autorizzazione non è possibile passare un token di accesso direttamente in un parametro URL perché i parametri URL fanno parte della richiesta HTTP, quindi qualsiasi server / router intermedio attraverso il quale la richiesta passerà (potrebbe essere centinaia) potrebbe essere in grado di leggere il token di accesso se non si utilizza la connessione crittografata (HTTPS) consentendo i cosiddetti attacchi Man-in-the-middle.

Il passaggio del token di accesso direttamente in un parametro URL potrebbe in teoria essere possibile, ma auth sever dovrebbe assicurarsi che l'URI di reindirizzamento utilizzi HTTPS con la crittografia TLS e un certificato SSL "attendibile" (in genere da un'autorità di certificazione che non è gratuita) per essere sicuri che il server di destinazione sia legittimo e che la richiesta HTTP sia completamente crittografata. Avere tutti gli sviluppatori di acquistare un certificato SSL e configurare correttamente SSL nel proprio dominio sarebbe un enorme problema e rallenterebbe enormemente l'adozione. Questo è il motivo per cui viene fornito un "codice di autorizzazione" intermedio utilizzabile una sola volta che solo il ricevitore legittimo sarà in grado di scambiare (perché è necessario il client segreto) e che il codice sarà inutile per i potenziali hacker che intercettano le richieste su transazioni non criptate (perché non conoscono il segreto del cliente).

Si potrebbe anche obiettare che il flusso implicito è meno sicuro, ci sono potenziali vettori di attacco come lo spoofing del dominio al reindirizzamento, ad esempio dirottando l'indirizzo IP del sito Web del cliente. Questo è uno dei motivi per cui il flusso implicito concede solo token di accesso (che dovrebbero avere un uso limitato nel tempo) e non aggiornare mai i token (che sono illimitati nel tempo). Per ovviare a questo problema, ti consiglio di ospitare le tue pagine web su un server abilitato HTTPS ogni volta che è possibile.