OAuth 2.0 - Il buono, il brutto e il cattivo

In un mondo dominato dai social media, è difficile non imbattersi in un'applicazione client che hai utilizzato per accedere a risorse riservate su altri server, ad esempio potresti aver usato un'applicazione basata sul web (come il NY Times) per condividere un interessante articolo di notizie sulla bacheca di Facebook o tweet su di esso. Oppure potresti aver usato l'app per iPhone di Quora che accede al tuo profilo Facebook o Google+ e personalizza i risultati in base ai dati del tuo profilo, come suggerire di aggiungere / invitare altri utenti a Quora, in base al tuo elenco di amici. La domanda è: in che modo queste applicazioni ottengono l'accesso ai tuoi account Facebook, Twitter o Google+ e in che modo possono accedere ai tuoi dati riservati? Prima che possano farlo, devono presentare alcune forme di credenziali di autenticazione e autorizzazioni di autorizzazione al server delle risorse.


Introduzione a OAuth 2.0

OAuth è spesso descritto come una chiave di valet per il web.

Ora, sarebbe davvero uncool condividere le tue credenziali Facebook o Google con qualsiasi applicazione client di terze parti che deve solo conoscere i tuoi amici, in quanto non solo fornisce all'app l'accesso illimitato e indesiderato al tuo account, ma ha anche la debolezza intrinseca associata alle password. È qui che entra in gioco OAuth, in quanto delinea una struttura di accesso / delega / autorizzazione che può essere utilizzata senza la necessità di condividere password. Per questo motivo, OAuth è spesso descritto come una chiave di valet per il web. Può essere pensato come una chiave speciale che consente l'accesso a funzioni limitate e per un periodo limitato di tempo senza dare via il pieno controllo, proprio come la chiave di accesso per un'automobile consente al parcheggiatore di guidare l'auto per un breve tratto, bloccando accesso al bagagliaio e al telefono cellulare di bordo.

Tuttavia, OAuth non è un nuovo concetto, ma una standardizzazione e la saggezza combinata di molti protocolli ben consolidati. Inoltre, vale la pena notare che OAuth non è solo limitato alle applicazioni dei social media, ma fornisce un modo standardizzato per condividere le informazioni in modo sicuro tra i vari tipi di applicazioni che espongono le loro API ad altre applicazioni. OAuth 2.0 ha una prosa completamente nuova e non è retrocompatibile con le sue specifiche precedenti. Detto questo, sarebbe opportuno prima di tutto coprire alcuni vocaboli di base di OAuth2.0 prima di immergersi in ulteriori dettagli.

  • Proprietario delle risorse : Un'entità in grado di garantire l'accesso a una risorsa protetta. La maggior parte delle volte è un utente finale.
  • Cliente : Un'applicazione che effettua richieste di risorse protette per conto del proprietario della risorsa e con la sua autorizzazione. Può essere un'applicazione basata su server, mobile (nativa) o desktop.
  • Server di risorse : Il server che ospita le risorse protette, in grado di accettare e rispondere alle richieste di risorse protette.
  • Server di autorizzazione : L'accesso al server che rilascia concede / token al client dopo aver autenticato con successo il proprietario della risorsa e ottenuto l'autorizzazione.
  • Token di accesso : I token di accesso sono credenziali presentate dal client al server di risorse per accedere alle risorse protette. Normalmente è una stringa che consiste in un ambito specifico, una durata e altri attributi di accesso e può contenere autonomamente le informazioni di autorizzazione in modo verificabile.
  • Aggiorna token : Sebbene non richiesto dalla specifica, i token di accesso hanno idealmente un tempo di scadenza che può durare da pochi minuti a diverse ore. Una volta scaduto un token di accesso, il client può richiedere al server di autorizzazione di emettere un nuovo token di accesso utilizzando il token di aggiornamento emesso dal server di autorizzazione.

Cosa c'è di sbagliato con OAuth 1.0?

Il principale svantaggio di OAuth 1.0 era la complessità intrinseca necessaria per implementare le specifiche.

Niente! Twitter funziona ancora perfettamente con OAuth 1.0 e ha appena iniziato a supportare una piccola parte delle specifiche 2.0. OAuth 1.0 era una specifica ben pensata e consentiva lo scambio di informazioni segrete in modo sicuro senza il sovraccarico imposto da SSL. Il motivo per cui avevamo bisogno di un rinnovamento era basato principalmente sulla complessità affrontata nell'implementazione delle specifiche. Di seguito sono riportate alcune aree in cui OAuth 1.0 non è riuscito a impressionare:

  • Firma di ogni richiesta : Avere il client generare firme su ogni richiesta API e convalidarle sul server ogni volta che viene ricevuta una richiesta, si è rivelato un grave ostacolo per gli sviluppatori, poiché hanno dovuto analizzare, codificare e ordinare i parametri prima di effettuare una richiesta. OAuth 2.0 ha rimosso questa complessità semplicemente inviando i token su SSL, risolvendo lo stesso problema a livello di rete. Non sono richieste firme con OAuth 2.0.
  • Indirizzamento di applicazioni native : Con l'evoluzione delle applicazioni native per dispositivi mobili, il flusso web di OAuth 1.0 sembrava inefficiente, imponendo l'uso di user-agent come un browser web. OAuth 2.0 ha ospitato più flussi specificamente adatti per applicazioni native.
  • Cancella separazione dei ruoli : OAuth 2.0 fornisce la necessaria separazione dei ruoli per il server delle autorizzazioni che autentica e autorizza il client e quello del server delle risorse che gestisce le chiamate API per accedere alle risorse riservate.

OAuth 2.0 in profondità

Prima di iniziare il protocollo, il client deve registrarsi con il server di autorizzazione fornendo il suo tipo di client, il suo URL di reindirizzamento (dove desidera che il server di autorizzazione reindirizzi dopo che il proprietario della risorsa concede o rifiuta l'accesso) e qualsiasi altra informazione richiesta dal server ea sua volta, viene fornito un identificativo client (client_id) e un segreto client (client_secret). Questo processo è noto come registrazione del cliente. Dopo la registrazione, il client può adottare uno dei seguenti flussi per interagire con il server.

Vari flussi di OAuth

OAuth 2.0 apporta cinque nuovi flussi alla tabella e offre agli sviluppatori la flessibilità necessaria per implementare uno di essi, a seconda del tipo di client coinvolto:

  • Flusso utente-agente : Adatto per client tipicamente implementati in user-agent (ad esempio, client in esecuzione all'interno di un browser Web) che utilizzano un linguaggio di scripting come JavaScript. Utilizzati principalmente da applicazioni native per dispositivi mobili o desktop, sfruttando il browser incorporato o esterno come user-agent per l'autorizzazione e utilizzando il Sovvenzione implicita autorizzazione.
  • Flusso del server Web : Questo usa il codice di autorizzazione concessione ed è un flusso basato sul reindirizzamento che richiede l'interazione con l'utente-agente dell'utente finale. Pertanto, è più adatto per i client che fanno parte di applicazioni basate su server Web, generalmente accessibili tramite un browser web.
  • Flusso di nome utente e password : Utilizzato solo quando esiste un elevato livello di attendibilità tra il client e il proprietario della risorsa e quando altri flussi non sono vitali, poiché implica il trasferimento delle credenziali del proprietario della risorsa. Esempi di client possono essere un sistema operativo del dispositivo o un'applicazione altamente privilegiata. Questo può anche essere utilizzato per migrare i client esistenti utilizzando gli schemi di autenticazione HTTP di base o Digest su OAuth convertendo le credenziali archiviate in un token di accesso.
  • Flusso di asserzioni : Il client può presentare un'asserzione come SAML Assertion al server di autorizzazione in cambio di un token di accesso.
  • Flusso di credenziali del cliente : OAuth viene utilizzato principalmente per l'accesso delegato, ma ci sono casi in cui il client possiede la risorsa o è già stato concesso l'accesso delegato al di fuori di un flusso OAuth tipico. Qui basta scambiare le credenziali del cliente per un token di accesso.

Discutere ogni flusso in dettaglio sarebbe fuori dallo scopo di questo articolo e preferirei leggere la specifica per informazioni di flusso approfondite. Ma per avere un'idea di cosa sta succedendo, approfondiamo uno dei flussi più utilizzati e supportati: il flusso del server Web.

Il flusso del server Web

Poiché si tratta di un flusso basato sul reindirizzamento, il client deve essere in grado di interagire con l'agente utente del proprietario della risorsa (che nella maggior parte dei casi è un browser Web) e quindi è in genere adatto per un'applicazione Web. Il diagramma seguente è una vista a volo d'uccello di come l'utente finale (o il proprietario della risorsa) utilizza l'applicazione client (in questo caso l'applicazione basata su server Web) per autenticare e autorizzare con il server di autorizzazione, per accedere alle risorse protette dal server delle risorse.


Autentica e autorizza il cliente

Il client, per conto del proprietario della risorsa, avvia il flusso reindirizzandolo all'endpoint di autorizzazione con un parametro response_type come codice, un identificativo client, che si ottiene durante la registrazione del client, un URL di reindirizzamento, un ambito richiesto (facoltativo) e uno stato locale (se presente). Per avere un'idea di come funziona davvero, ecco uno screenshot di come dovrebbe apparire una tipica richiesta / risposta:


Questo di solito presenta al proprietario della risorsa un'interfaccia web, in cui il proprietario può autenticarsi e verificare quali sono le autorizzazioni che l'app client può utilizzare per conto del proprietario.


Supponendo che il proprietario della risorsa conceda l'accesso al client, il server di autorizzazione reindirizza l'utente-agente al client utilizzando l'URL di reindirizzamento fornito in precedenza, insieme al codice di autorizzazione come mostrato dalla risposta sotto.


Codice di autorizzazione allo scambio per token

Il cliente allora messaggi a un altro endpoint di autorizzazione e invia il codice di autorizzazione ricevuto nel passaggio precedente, insieme all'URL di reindirizzamento, al relativo identificativo e segreto del client, ottenuto durante la registrazione del client e un parametro grant_type deve essere impostato come codice di autorizzazione.


Il server quindi convalida il codice di autorizzazione e verifica che l'URL di reindirizzamento sia uguale a quello del passaggio precedente. Se ha successo, il server risponde con un token di accesso e, facoltativamente, un token di aggiornamento.


Richiedi risorse limitate utilizzando i token di accesso

Il cliente può ora utilizzare le API fornite dall'implementazione e può interrogare il server delle risorse per una risorsa limitata passando il token di accesso nell'intestazione Autorizzazione della richiesta. Una richiesta CURL di esempio all'API di Blogger di Google per ottenere un blog, dato il suo identificativo, sarebbe simile a questa:

 $ curl https://www.googleapis.com/blogger/v3/blogs/5223788876950011016 -H 'Autorizzazione: OAuth ya29.AHES6ZRTj1GNxAby81Es-p_YPWWNBAFRvBYVsYj2HZJfJHU'

Si noti che abbiamo aggiunto il token di accesso come intestazione di autorizzazione nella richiesta e inoltre si è fatto fuoriuscire il token includendolo tra virgolette singole, poiché il token potrebbe contenere caratteri speciali. Tieni presente che l'escape del token di accesso è richiesto solo quando si utilizza l'arricciatura. Risulta nell'invio della seguente richiesta:


Il server di risorse verifica quindi le credenziali passate (token di accesso) e, in caso di esito positivo, risponde con le informazioni richieste.


Questi esempi sono gentilmente concessi da OAuth2.0 Playground e sono tipici del modo in cui Google implementa le specifiche. Differenze potrebbero essere osservate quando si prova lo stesso flusso con altri provider (come Facebook o Salesforce) e questo è il punto in cui i problemi di interoperabilità si insinuano, di cui discuteremo un po 'più tardi.

Token di accesso di aggiornamento

Sebbene non richiesto dalla specifica, ma in genere i token di accesso sono di breve durata e hanno una scadenza. Pertanto, quando un token di accesso è scaduto, il client invia il token di aggiornamento al server di autorizzazione, insieme al suo identificatore e segreto del client e un parametro grant_type come refresh_token.


Il server di autorizzazione risponde quindi con il nuovo valore per il token di accesso.


Sebbene esista un meccanismo per revocare il token di aggiornamento emesso, ma normalmente il token di aggiornamento è permanente e deve essere protetto e trattato come un valore segreto.


Cosa c'è di sbagliato con OAuth 2.0?

La roba buona

Andando per il tasso di adozione, OAuth 2.0 è sicuramente un miglioramento rispetto al suo predecessore arcano. Le istanze di comunità di sviluppatori che vacillano mentre implementano le firme di 1.0 non sono sconosciute. OAuth 2.0 offre anche diversi nuovi tipi di concessione, che possono essere utilizzati per supportare molti casi d'uso come le applicazioni native, ma l'USP di questa specifica è la sua semplicità rispetto alla versione precedente.

Le parti cattive

Ci sono alcuni punti in sospeso nelle specifiche, in quanto non riesce a definire correttamente alcuni componenti richiesti o li lascia alle implementazioni per decidere, come ad esempio:

È probabile che le estremità libere nelle specifiche OAuth 2.0 producano una vasta gamma di implementazioni non interoperabili.

  • interoperabilità: L'aggiunta di troppe estensioni nelle specifiche ha portato a implementazioni non compatibili tra loro, il che significa che non è possibile sperare di scrivere un codice generico che utilizza Endpoint Discovery per conoscere gli endpoint forniti dalle diverse implementazioni e interagire con loro, piuttosto dovresti scrivere pezzi di codice separati per Facebook, Google, Salesforce e così via. Persino le specifiche ammettono questo fallimento come un disclaimer.
  • Token short Lived: Le specifiche non impongono la durata e la portata dei token emessi. L'implementazione è gratuita per far vivere un token per sempre. Sebbene la maggior parte delle implementazioni ci fornisca token di accesso di breve durata e un token di aggiornamento, che può essere utilizzato per ottenere un nuovo token di accesso.
  • Sicurezza: Le specifiche "raccomandano" l'uso di SSL / TLS mentre inviano i token in chiaro sul filo. Sebbene, ogni implementazione importante abbia reso obbligatorio l'uso di endpoint di autorizzazione sicuri, il client deve disporre di un URL di reindirizzamento sicuro, altrimenti sarà troppo facile per un utente malintenzionato intercettare la comunicazione e decifrare i token.

The Ugly Spat

Sono stati necessari circa 31 progetti di versioni e le dimissioni dell'autore / sviluppatore principale Eran Hammer del comitato per pubblicare finalmente le specifiche. Eran ha suscitato una polemica chiamando le specifiche "un cattivo protocollo e un caso di morte da mille tagli". Secondo lui, l'utilizzo di token al portatore (invio di token su SSL senza firma o altra verifica) sull'utente di firme (o token MAC), utilizzati in OAuth 1.0 per firmare la richiesta, è stata una mossa sbagliata e un risultato di divisione degli interessi tra il web e le comunità di imprese.


Osservazioni conclusive

Le specifiche lasciano sicuramente aperte molte estensioni, con il risultato di implementazioni che introducono i propri parametri, oltre a quello che le specifiche già definiscono, e si assicura che le implementazioni di provider diversi non possano interagire tra loro. Ma andando con la popolarità e il tasso di adozione di questo quadro, con ogni grande giocatore in città (Google, Twitter, Facebook, Salesforce, Foursquare, Github ecc.) Implementando e modificando il modo in cui gli si addice, OAuth è ben lungi dall'essere un fallimento . In effetti, qualsiasi applicazione web che prevede di esporre le proprie API ad altre applicazioni Web deve supportare qualche forma di autenticazione e autorizzazione e OAuth si adatta al progetto qui.

Per ulteriori letture

  • OAuth e la strada dell'inferno
  • OAuth - Un'introduzione
  • RFC 5849 - Specifiche OAuth1.0
  • RFC 6749 - Specifiche OAuth2.0