2015-12-20 14 views
7

Supponiamo di avere alcune API RESTful le cui risorse esposte vogliamo esporre. Gli utenti finali lavoreranno con questa API attraverso applicazioni client come app mobili e client basati su Javascript che girano su browser web.Come verificare quali risorse possono accedere a ciascun utente con OAuth e OpenID Connect?

Con OAuth 2.0 questa API RESTful giace sul Resource Server e avremo un server di autorizzazione sul quale sono registrate le applicazioni client. Gli utenti saranno quindi registrati sul server di autorizzazione e potranno concedere l'autorizzazione a tali applicazioni per accedere alle risorse per loro conto o meno.

Pertanto, quando l'utente accede a un'applicazione client, verrà reindirizzato al server di autorizzazione e verrà richiesto di concedere le autorizzazioni a detta app client. Successivamente viene emesso un token di accesso e il client è in grado di effettuare richieste al server di risorse.

Tutto questo è abbastanza chiaro per me. C'è solo un pezzo mancante: la protezione di ogni risorsa potrebbe dipendere dall'utente. Per essere più precisi potrebbe essere dipendente dalle richieste. Quello che voglio dire con questo è che possiamo avere la seguente situazione:

Quando ho sentito parlare di OAuth che fare con ASP.NET WebAPI e ho affrontato che nel seguente modo: quando la richiesta è stata inviata con l'intestazione Authorization: Bearer [token], sul lato server principale thread è stato impostato e io pensavo che questo significasse che l'utente era autenticato con l'API. Quindi ho usato gli attributi [Authorize] per verificare se l'utente potesse accedere alla risorsa.

Dopo aver studiato OAuth più profondamente, ho visto che si trattava di un terribile abuso del protocollo. Come ho appreso, OAuth autorizza le applicazioni e non gli utenti. Quando ho effettuato la richiesta con l'intestazione Autorizzazione, come ho appreso, il token di accesso non dovrebbe contenere informazioni sull'utente, solo sull'applicazione che può fare la richiesta.

Considerando che, l'invio dell'intestazione Autorizzazione con la richiesta non identifica l'utente e non dice se l'utente può o non può accedere a detta risorsa.

In tal caso, come si esegue questo tipo di autorizzazione? Voglio dire, non l'autorizzazione dell'app client che esegue la richiesta, ma l'autorizzazione dell'utente che accede alla risorsa in base alle sue affermazioni? Credo che sia qui che entra OpenID Connect e sono i token ID, ma non sono sicuro. Come si gestisce questo?

risposta

8

Un token di accesso non contiene rivendicazioni dell'utente, ma contiene l'oggetto dell'utente che ha concesso le autorizzazioni all'applicazione client. "Oggetto" è un termine tecnico e indica un identificativo univoco. Semplicemente dicendo "soggetto" è un ID utente nel tuo database.

In un endpoint risorsa protetta, si farà:

  1. estrarre un token di accesso dalla richiesta.(RFC 6750)
  2. Ottenere informazioni dettagliate sul token di accesso dal server di autorizzazione. (RFC 7662)
  3. Convalidare il token di accesso. La convalida include (a) se il token di accesso è scaduto o meno, e (b) se il token di accesso copre ambiti (permessi) richiesti dall'endpoint della risorsa protetta.

I passaggi precedenti da 1 a 3 sono un controllo di accesso contro le applicazioni client . OAuth 2.0 (RFC 6749) è per questo. Vedere "Protected Resource" di Authlete (da me) per i dettagli su questi passaggi.

Dopo i passaggi di cui sopra, allora si farà:

  1. estrarre il soggetto dal token di accesso. Di nuovo, "soggetto" è un identificativo univoco dell'utente.
  2. Recupera le richieste dell'utente dal tuo database.
  3. Convalida le affermazioni come preferisci.

I passaggi precedenti da 4 a 6 sono un controllo di accesso contro utenti. OAuth 2.0 NON è per questo.

Lo scopo principale di OpenID Connect è ottenere un ID token in modo verificabile. È possibile confermare che un token ID è stato emesso da un utente autorizzato verificando la firma allegata al token ID. Vedere JSON Web Signature (JWS) (RFC 7515) per i dettagli sulla firma.

Un token ID non è una tecnologia per proteggere le API Web. Potrebbe tuttavia essere possibile utilizzarlo a tale scopo se si utilizza correttamente il reclamo at_hash in un token ID (vedere "3.1.3.6. ID Token" in OpenID Connect Core 1.0). Tuttavia, in un endpoint di risorsa protetto, sarà molto più semplice ottenere le attestazioni direttamente dal database piuttosto che analizzare un token ID.


[risposta supplementare # 1 per il commento]

Nel vostro caso d'uso, non occorre token ID. È perché un token di accesso contiene già informazioni sull'argomento dell'utente. In casi normali, l'informazione equivale al valore della rivendicazione sub in un token ID.

enter image description here

Pertanto, non è necessario un token ID per ottenere il soggetto dell'utente. Vedere la descrizione del passaggio 4 e è possibile trovare "estrai l'oggetto dal token di accesso ".


[risposta supplementare # 2 per il commento]

Quindi è qualcosa che non va nel estraendo il soggetto dal token di accesso così e verificare le affermazioni? O questo è il modo giusto di fare le cose?

Non c'è niente di sbagliato. Ad esempio, si supponga di definire un'API Web, https://api.example.com/profile, che restituisca le informazioni del profilo di un utente. In casi normali, tale API accetta un token di accesso e quindi estrae l'oggetto dal token di accesso per determinare a quale utente fare riferimento. D'altra parte, se l'API non ha estratto l'oggetto dal token di accesso, dovrebbe richiedere "subject" come parametro di richiesta per determinare a quale utente fare riferimento (o richiedere un token ID che contenga una rivendicazione "sub") . Anche in questo caso, l'API deve verificare se l'argomento specificato dal parametro di richiesta e l'oggetto associato al token di accesso sono identici perché altrimenti diventerebbe un problema di sicurezza.

Anche il controllo delle attestazioni dopo l'estrazione del soggetto è un passaggio normale. Ad esempio, è possibile limitare le funzionalità del servizio in base al piano pagato dall'utente (piano gratuito, piano Lite, piano aziendale o altro). In questo caso, dovresti fare riferimento al reclamo plan. Ovviamente, il controllo di tale richiesta può essere effettuato solo dopo aver estratto l'oggetto dal token di accesso.

Pertanto, (1) l'estrazione dell'oggetto da un token di accesso e quindi (2) la verifica delle affermazioni dell'utente sono normali e anche tipici passaggi nelle implementazioni degli endpoint delle risorse protette.

+0

Grazie ancora per l'aiuto @TakahikoKawasaki. Penso di averlo capito ora. Alla fine utilizziamo il token di accesso OAuth per avere il controllo di accesso contro le applicazioni client: quale client può accedere a quale risorsa. Quindi dal token di identità OpenID Connect abbiamo il controllo dell'accesso agli utenti: selezioniamo il reclamo soggetto dal token ID che identifica gli utenti e guarda il database se l'utente ha le richieste richieste per accedere alla risorsa. Alla fine, invece di spostare le attestazioni in giro, spostiamo il soggetto all'interno del token di identità e verifichiamo le richieste necessarie all'autorizzazione. È così? – user1620696

+0

Modificato la risposta per il tuo commento. –

+0

Grazie per la risposta dettagliata @TakahikoKawasaki. Solo un punto, hai detto nel passaggio 4 "OAuth 2.0 NON è per questo" e lo capisco, poiché l'obiettivo di OAuth è il controllo dell'accesso contro le applicazioni client. Quindi c'è qualcosa di sbagliato nell'estrarre l'argomento dal token di accesso in questo modo e verificare le affermazioni? O questo è il modo giusto di fare le cose? Ci scusiamo per tanti dubbi, non sono davvero un esperto in sicurezza e sto solo iniziando con OAuth e OpenID Connect. – user1620696

1

Hai ragione, OAuth è NOT an authentication protocol ma piuttosto un protocollo di delega.

OpenID Connect aggiunge due costrutti di identità notabili al modello di emissione token di OAuth 2.0.

  • un token di identità - la cui consegna da un partito all'altro può consentire un'esperienza utente Federated Identity SSO

  • un'identità standardizzato attributo API - in cui un client può
    richiama i desiderata identità attributi per un determinato utente.

L'ID token può essere presentato al userinfo_endpoint per ottenere le informazioni e fornisce livello di garanzia che l'utente è stato autenticato dal provider OpenID.

BTW: il "sub" vale a dire unico nel contesto del server di autorizzazione. Si consiglia SE SE si memorizza il sub si memorizza anche qualcosa come iss-sub. I pensieri su Tsmith su Google potrebbero non essere utili su Twitter

Problemi correlati