Secure REST API e Single Page App utilizzando il codice di autorizzazione OAuth 2 esterno

11

Sto cercando di capire come implementare un flusso di codice di autorizzazione OAuth 2 quando si dispone sia di un'app JS a singola pagina sia di un'API REST. L'obiettivo è proteggere l'accesso all'API REST scaricando l'autenticazione dal provider OAuth.

Attualmente il mio flusso assomiglia a:

1)

+--------------------+               +----------------+
| JS Single Page App | - redirect -> | OAuth Provider | - user enters credentials
+--------------------+               +----------------+

2)

+----------------+                                   +----------+
| OAuth Provider | - redirect with temporary code -> | REST API |
+----------------+                                   +----------+

3)

+----------+                                      +----------------+
| REST API | - request access token using code -> | OAuth Provider |
+----------+ <- return access token ------------- +----------------+

Cosa dovrei fare ora? La mia attuale comprensione è che dovrei reindirizzare l'utente dopo aver ricevuto il token di accesso a una pagina che caricherà di nuovo l'app Single Page di JS. Ma dovrei condividere il token di accesso con l'app a singola pagina e utilizzare la presenza di esso per autenticare qualsiasi richiesta che colpisce la mia API REST, oppure è meglio creare un identificatore separato e mantenere un mapping sul lato server tra new-identifier->access_token ? In entrambi i casi quale sarebbe il modo migliore per trasferire qualsiasi identificativo al cliente? Preferirei non mantenere alcuna sessione e non avere l'identificatore visualizzato nella barra degli indirizzi della pagina reindirizzata. L'unica cosa che posso attualmente pensare sarebbe creare un cookie temporaneo che l'app a singola pagina dovrebbe leggere e quindi cancellare, ma in qualche modo sembra un po 'goffo.

    
posta Anvar Karimson 13.09.2014 - 11:40
fonte

2 risposte

11

In primo luogo, e per essere molto chiari, OAuth 2 non è un protocollo di autenticazione. Se desideri conoscere l'identità dell'utente, esistono altri protocolli progettati per risolvere questo problema, come ad esempio OpenID Connect . Se intendi utilizzare OAuth 2 allo scopo di autorizzare l'accesso alle tue risorse protette, continua a leggere.

Per rispondere alla tua domanda diretta: sembra che tu stia utilizzando il sussidio per il codice di autorizzazione :

 +----------+
 | Resource |
 |   Owner  |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier      +---------------+
 |         -+----(A)-- & Redirection URI ---->|               |
 |  User-   |                                 | Authorization |
 |  Agent  -+----(B)-- User authenticates --->|     Server    |
 |          |                                 |               |
 |         -+----(C)-- Authorization Code ---<|               |
 +-|----|---+                                 +---------------+
   |    |                                         ^      v
  (A)  (C)                                        |      |
   |    |                                         |      |
   ^    v                                         |      |
 +---------+                                      |      |
 |         |>---(D)-- Authorization Code ---------'      |
 |  Client |          & Redirection URI                  |
 |         |                                             |
 |         |<---(E)----- Access Token -------------------'
 +---------+       (w/ Optional Refresh Token)

Questo flusso è ottimizzato per client riservati : client che possono mantenere un segreto dell'utente finale e di eventuali terze parti che potrebbero tentare di accedere alle risorse protette. Nel caso di un'applicazione javascript in esecuzione nel browser del client, non è possibile mantenere un segreto - tutto il codice è lì e semplicemente vi si irrompe con il debugger del browser rivela tutti i segreti.

Invece, c'è il flusso di Grant implicito , ottimizzato specificamente per clienti come il tuo. RFC utilizza anche JavaScript in esecuzione in un browser come esempio di un client destinato a utilizzare questo flusso.

 +----------+
 | Resource |
 |  Owner   |
 |          |
 +----------+
      ^
      |
     (B)
 +----|-----+          Client Identifier     +---------------+
 |         -+----(A)-- & Redirection URI --->|               |
 |  User-   |                                | Authorization |
 |  Agent  -|----(B)-- User authenticates -->|     Server    |
 |          |                                |               |
 |          |<---(C)--- Redirection URI ----<|               |
 |          |          with Access Token     +---------------+
 |          |            in Fragment
 |          |                                +---------------+
 |          |----(D)--- Redirection URI ---->|   Web-Hosted  |
 |          |          without Fragment      |     Client    |
 |          |                                |    Resource   |
 |     (F)  |<---(E)------- Script ---------<|               |
 |          |                                +---------------+
 +-|--------+
   |    |
  (A)  (G) Access Token
   |    |
   ^    v
 +---------+
 |         |
 |  Client |
 |         |
 +---------+

Dovresti leggere l'RFC per i dettagli su come funziona questo flusso, ma il concetto generale del flusso non richiede più l'uso di un codice di autorizzazione; al client viene assegnato direttamente il codice di accesso.

Questo ha lo svantaggio che quando il codice non è più valido, il client deve richiedere nuovamente la risorsa - non c'è modo di "ricordare" la concessione dell'autorizzazione per un client che non è in grado di mantenere un segreto. Questa è una decisione intenzionale presa dagli autori di OAuth per migliorare la sicurezza dei clienti di questa natura.

    
risposta data 17.09.2014 - 15:34
fonte
0

Non sono sicuro di aver compreso il tuo scenario corretto. Se si desidera proteggere solo le chiamate API RESTful da un client javascript con OAuth, la risposta di Tragedian relativa al tipo di concessione implicita è assolutamente corretta. Ciò significa che hai una chiara segregazione di interfaccia utente e dati:

  • L'interfaccia utente (vale a dire l'applicazione JS a pagina singola) può essere caricata senza alcuna forma di autenticazione / autorizzazione
  • I dati (ad esempio le chiamate API RESTful) sono protetti con token di accesso DOPO essere autorizzati dal server di autorizzazione

Se hai uno scenario diverso, descrivilo in modo più preciso. Si menziona qualcosa di una parte di backend dell'applicazione che si basa anche su OAuth e che è in grado di memorizzare dati sensibili. Ciò significherebbe che, accanto all'app JS a pagina singola, un client DIVERSO (in linguaggio OAuth) ...

    
risposta data 22.09.2014 - 09:29
fonte

Leggi altre domande sui tag