OAuth 2.0 - Bine, Rău și Ugly

Într-o lume dominată de medii sociale, este greu să nu intri într-o aplicație client pe care ați folosit-o pentru a accesa resurse restricționate pe un alt server, de exemplu, este posibil să fi folosit o aplicație web (cum ar fi NY Times) articol de știri interesant pe peretele dvs. pe Facebook sau tweet despre el. Sau ați fi putut folosi aplicația iPhone a lui Quora care accesează profilul dvs. Facebook sau Google+ și personalizează rezultatele pe baza datelor din profil, cum ar fi sugerând adăugarea / invitarea altor utilizatori la Quora, pe baza listei de prieteni. Întrebarea este cum pot accesa aceste aplicații conturile dvs. Facebook, Twitter sau Google+ și cum pot accesa datele dvs. confidențiale? Înainte de a putea face acest lucru, ei trebuie să prezinte o anumită formă de acreditare de autentificare și granturi de autorizare pentru serverul de resurse.


Introducere în OAuth 2.0

OAuth este adesea descrisă ca o cheie valet pentru web.

Acum ar fi într-adevăr porcos să distribuiți acreditările dvs. Facebook sau Google cu orice aplicație client terță parte, care trebuie doar să știe despre prietenii dvs., deoarece nu numai că oferă aplicației acces nelimitat și nedorit la contul dvs., dar are și slăbiciunea inerentă asociată cu parolele. Acesta este locul în care OAuth intră în joc deoarece conturează un cadru de delegare a accesului / autorizare care poate fi folosit fără a fi necesară partajarea parolelor. Din acest motiv, OAuth este adesea descris ca o cheie valet pentru web. Acesta poate fi considerat ca o cheie specială care permite accesul la caracteristici limitate și pentru o perioadă limitată de timp, fără a renunța la controlul complet, la fel cum tasta valet pentru o mașină permite participantului la parcare să conducă mașina pentru o distanță scurtă, blocând accesul la portbagaj și la telefonul mobil de la bord.

Cu toate acestea, OAuth nu este un concept nou, ci o înțelepciune standardizată și combinată a multor protocoale bine stabilite. De remarcat este faptul că OAuth nu se limitează numai la aplicațiile social-media, ci oferă o modalitate standard de a partaja informațiile în siguranță între diverse tipuri de aplicații care expun API-urile lor altor aplicații. OAuth 2.0 are o proză complet nouă și nu este compatibilă cu versiunea precedentă. După ce am spus acest lucru, ar fi bine să acoperim mai întâi un vocabular de bază OAuth2.0 înainte de a se scufunda în detalii suplimentare.

  • Proprietarul resurselor : O entitate capabilă să acorde acces la o resursă protejată. De cele mai multe ori, este un utilizator final.
  • Client : O aplicație care face solicitări de resurse protejate în numele proprietarului resursei și cu autorizația sa. Poate fi o aplicație bazată pe server, mobil (nativ) sau desktop.
  • Resurse Server : Serverul care găzduiește resursele protejate, capabil să accepte și să răspundă solicitărilor de resurse protejate.
  • Server de autorizare : Serverul emite granturi / jetoane de acces clientului după autentificarea cu succes a proprietarului resursei și obținerea autorizației.
  • Jeton de acces : Token-urile de acces sunt acreditările prezentate de client către serverul de resurse pentru a accesa resurse protejate. În mod normal, este vorba despre un șir constând dintr-un domeniu specific de acoperire, durata de viață și alte atribute de acces și poate conține informațiile de autorizare într-un mod verificabil.
  • Actualizați Token : Deși nu sunt mandatate de spec., Tokenurile de acces au în mod ideal un timp de expirare care poate dura oriunde de la câteva minute la mai multe ore. Odată ce un indice de acces a expirat, clientul poate solicita serverului de autorizare să emită un nou simbol de acces folosind jetonul de reîmprospătare emis de serverul de autorizare.

Ce este greșit cu OAuth 1.0?

Principalul dezavantaj al OAuth 1.0 a fost complexitatea inerentă necesară implementării spec.

Nimic adevărat! Twitter funcționează perfect cu OAuth 1.0 și tocmai a început să susțină o mică parte din spec. 2.0. OAuth 1.0 a fost o spec. Bine gândit și a permis schimbul de informații secrete în siguranță fără costurile generale impuse de SSL. Motivul pentru care aveam nevoie de o revizuire se bazează în mare parte pe complexitatea cu care se confruntă implementarea spec. Următoarele sunt câteva zone în care OAuth 1.0 nu a reușit să impresioneze:

  • Semnarea fiecărei solicitări : A avea clientul să genereze semnături pe fiecare solicitare API și să le valideze pe serverul de fiecare dată când cererea a fost primită, sa dovedit a fi un obstacol major pentru dezvoltatori, deoarece trebuiau să analizeze, să codifice și să sorteze parametrii înainte de a face o solicitare. OAuth 2.0 a eliminat această complexitate prin simpla trimitere a jetoanelor prin SSL, rezolvând aceeași problemă la nivel de rețea. Nu sunt necesare semnături cu OAuth 2.0.
  • Adresați-vă aplicațiilor native : Odată cu evoluția aplicațiilor native pentru dispozitivele mobile, fluxul web al OAuth 1.0 părea ineficient, impunând utilizarea unor agenți utilizator ca un browser Web. OAuth 2.0 a găzduit mai multe fluxuri specifice pentru aplicații native.
  • Separarea clară a rolurilor : OAuth 2.0 furnizează separarea mult mai necesară a rolurilor pentru autentificarea și autorizarea serverului de autorizare și pentru apelurile API pentru gestionarea serverului de resurse pentru accesarea resurselor restricționate.

OAuth 2.0 în profunzime

Înainte de a iniția protocolul, clientul trebuie să se înregistreze la serverul de autorizare prin furnizarea tipului său de client, adresei sale de redirecționare (în cazul în care dorește ca serverul de autorizare să redirecționeze după ce proprietarul resurselor îi acordă sau respinge accesul) și orice alte informații solicitate de server și la rândul său, i se dă un identificator al clientului (client_id) și un client secret (client_secret). Acest proces este cunoscut sub numele de Înregistrare client. După înregistrare, clientul poate adopta unul din următoarele fluxuri pentru a interacționa cu serverul.

Diverse fluxuri OAuth

OAuth 2.0 aduce în jur de cinci noi fluxuri și oferă dezvoltatorilor flexibilitatea de a implementa oricare dintre ele, în funcție de tipul de client implicat:

  • Flux de utilizator-agent : Potrivit clienților, de obicei implementați în agenți utilizator (de exemplu, clienții care rulează în interiorul unui browser web) folosind o limbă de scripting, cum ar fi JavaScript. Utilizată în cea mai mare parte de aplicațiile native pentru dispozitive mobile sau desktop, care utilizează browserul încorporat sau extern ca agent de utilizator pentru autorizare și utilizează Grant implicit autorizare.
  • Web Server Flow : Acest lucru face uz de Cod de autorizare acordă și este un flux bazat pe redirecționare care necesită interacțiune cu agentul utilizator al utilizatorului final. Astfel, este cel mai potrivit pentru clienții care fac parte din aplicațiile bazate pe serverul web, accesate de obicei prin intermediul unui browser web.
  • Numele și fluxul parolei : Utilizată numai atunci când există o înaltă încredere între client și proprietarul resurselor și când alte fluxuri nu sunt viabile, deoarece implică transferul acreditărilor proprietarului resurselor. Exemple de clienți pot fi un sistem de operare pentru dispozitive sau o aplicație extrem de privilegiată. Acest lucru poate fi de asemenea utilizat pentru migrarea clienților existenți utilizând schemele HTTP Basic sau Digest Authentication în OAuth, prin transformarea acreditărilor stocate într-un simbol de acces.
  • Afirmația fluxului : Clientul dvs. poate prezenta o afirmație precum SAML Assertion pe serverul de autorizare în schimbul unui jeton de acces.
  • Client Credentials Flow : OAuth este utilizat în principal pentru accesul delegat, dar există cazuri în care clientul deține resursa sau a fost deja acordat accesul delegat în afara unui flux tipic OAuth. Aici schimbați acreditările clienților pentru un jeton de acces.

Discutarea fiecărui flux în detaliu ar depăși domeniul de aplicare al acestui articol și aș recomanda mai degrabă citirea spec. Pentru informații detaliate privind debitul. Dar pentru a obține o simțire pentru ceea ce se întâmplă, să săpăm mai adânc într-unul dintre cele mai utilizate și suportate fluxuri: Flow Server Web.

Fluxul serverului Web

Deoarece acesta este un flux bazat pe redirecționare, clientul trebuie să poată interacționa cu agentul utilizator al proprietarului resursei (care în majoritatea cazurilor este un browser web) și, prin urmare, este în mod obișnuit potrivit pentru o aplicație web. Diagrama de mai jos reprezintă o vizualizare a modului în care utilizatorul final (sau proprietarul resursei) utilizează aplicația client (aplicație bazată pe serverul web în acest caz) pentru autentificarea și autorizarea cu serverul de autorizare, pentru a accesa resursele protejate de către serverul de resurse.


Autentificați și autorizați Clientul

Clientul, în numele proprietarului resursei, inițiază fluxul redirecționat către punctul final de autorizare cu un parametru response_type ca cod, un identificator de client, obținut în timpul înregistrării clientului, o adresă URL de redirecționare, un domeniu solicitat (opțional) și o stare locală (dacă există). Pentru a vă simți cum funcționează cu adevărat, iată o captură de ecran a modului în care ar arăta o solicitare / răspuns tipic:


În mod normal, acesta prezintă proprietarului resursei o interfață web, în ​​care proprietarul poate autentifica și verifica ce permisiuni pe care aplicația client să le poată utiliza în numele proprietarului.


Presupunând că proprietarul resursei acordă acces la client, serverul de autorizare redirecționează agentul utilizator înapoi la client utilizând adresa URL de redirecționare furnizată anterior, împreună cu codul de autorizare, după cum se arată în răspunsul de mai jos.


Codul autorizației de schimb pentru jetoane

Clientul atunci posturi la un alt punct final al autorizației și trimite codul de autorizare primit în etapa anterioară împreună cu adresa URL de redirecționare, identificatorul clientului și secretul obținut în timpul înregistrării clientului și un parametru grant_type trebuie să fie setat ca Cod de autorizare.


Serverul apoi validează codul de autorizare și verifică faptul că adresa URL de redirecționare este aceeași ca în etapa anterioară. Dacă este reușit, serverul răspunde înapoi cu un jeton de acces și, opțional, cu un jeton de reîmprospătare.


Solicitați resurse restricționate utilizând Token-urile de acces

Clientul poate consuma acum API-urile furnizate de implementare și poate interoga serverul de resurse pentru o resursă restricționată prin trecerea de-a lungul tokenului de acces în antetul de autorizare al cererii. O solicitare de solicitare CURL la API-ul Blogger al Google pentru a obține un blog, având în vedere identificatorul său, ar arăta astfel:

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

Rețineți că am adăugat tokenul de acces ca antet de autorizare în solicitare și, de asemenea, am scăpat de token prin includerea în ghilimele simple, deoarece tokenul poate conține caractere speciale. Rețineți că evadarea simbolului de acces este necesară numai când utilizați curl. Rezultă trimiterea următoarei solicitări:


Serverul de resurse verifică apoi acreditările (permisul de acces) și, dacă reușește, răspunde înapoi la informațiile solicitate.


Aceste exemple sunt mulțumite de spațiul de joacă OAuth2.0 și sunt tipice pentru modul în care Google implementează specificațiile. Diferențele ar putea fi observate atunci când încercați același flux cu alți furnizori (cum ar fi Facebook sau Salesforce) și aici se întâlnesc problemele de interoperabilitate, despre care discutăm puțin mai târziu.

Cod de acces refresh

Deși nu sunt mandatate de spec., Dar de regulă tokenurile de acces sunt de scurtă durată și au un timp de expirare. Deci, atunci când un token de acces este expirat, clientul trimite tokenul de refresh la serverul de autorizare împreună cu identificatorul său client și secret și un parametru grant_type ca refresh_token.


Serverul de autorizare răspunde apoi înapoi cu noua valoare pentru tokenul de acces.


Deși există un mecanism pentru a revoca jetonul de reîmprospătare emis, dar în mod normal jetonul de refresh trăiește pentru totdeauna și trebuie protejat și tratat ca o valoare secretă.


Ce este greșit cu OAuth 2.0?

Lucrurile bune

Datorită ratei de adopție, OAuth 2.0 este cu siguranță o îmbunătățire față de predecesorul său arcane. Instanțele comunității de dezvoltatori faltering în timpul implementării semnăturilor de la 1.0 nu sunt cunoscute. OAuth 2.0 oferă, de asemenea, mai multe tipuri de subvenții noi, care pot fi utilizate pentru a suporta mai multe cazuri de utilizare, cum ar fi aplicațiile native, dar USP din această spec. Este simplitatea față de versiunea anterioară.

Părțile rele

Există câteva capete libere în caietul de sarcini, deoarece nu reușește să definească în mod corespunzător câteva componente necesare sau le lasă la dispoziție pentru a decide, cum ar fi:

Liniile terminale ale spec. OAuth 2.0 sunt de natură să producă o gamă largă de implementări neinteroperabile.

  • interoperabilitate: Adăugarea prea multor puncte de extensie în spec. A dus la implementări care nu sunt compatibile între ele, ceea ce înseamnă că nu puteți spera să scrieți o bucată generică de cod care utilizează Obiectivul Discovery să știți despre punctele finale oferite de diferitele implementări și să interacționați cu ele, mai degrabă ar trebui să scrieți bucăți separate de coduri pentru Facebook, Google, Salesforce și așa mai departe. Chiar și spec. Recunoaște acest eșec ca pe o declarație de neconcordanță.
  • Jetoane de scurtă durată: Speculația nu mandatează durata de viață și amploarea jetoanelor emise. Implementarea este liberă să aibă un token viu pentru totdeauna. Deși majoritatea implementărilor ne furnizează token-uri de acces de scurtă durată și un jet de reîmprospătare, care poate fi folosit pentru a obține un simbol de acces nou.
  • Securitate: Spec-ul doar "recomandă" utilizarea SSL / TLS în timp ce trimit token-urile în text peste fir. Cu toate că fiecare implementare majoră a făcut ca o cerință de a avea obiective securizate de autorizare și de a solicita clientului să aibă o adresă de redirecționare sigură, în caz contrar, va fi prea ușor pentru un atacator să asculte comunicarea și să descifreze jetoanele.

Ugly Spat

A luat IETF aproximativ 31 de versiuni de proiect și demisia autorului / dezvoltatorului principal Eran Hammer din comisie pentru a publica în cele din urmă spec. Eran a declanșat o controversă prin apelarea spec "un protocol proastă și un caz de moarte cu o mie de tăieturi". Potrivit acestuia, folosirea jetoanelor purtatoare (trimiterea de jetoane peste SSL fără semnarea acestora sau orice altă verificare) asupra utilizatorului semnaturilor (sau a MAC-Tokens), utilizat în OAuth 1.0 pentru a semna solicitarea, a fost o mișcare proastă și un rezultat de împărțire a intereselor între comunitățile web și întreprinderi.


Observații concludente

Spec-ul lasă cu desăvârșire multe puncte de extindere, rezultând în implementări care introduc parametrii proprii, în plus față de ceea ce definește deja speculația, și se asigură că implementările de la diferiți furnizori nu pot interconecta unul cu celălalt. Dar, mergând cu popularitatea și rata de adoptare a acestui cadru, cu fiecare jucător mare din oraș (Google, Twitter, Facebook, Salesforce, Foursquare, Github etc.) implementând și ajustând-o așa cum le convine, OAuth este departe de a fi un eșec . De fapt, orice aplicație web care intenționează să-și expună API-urile la alte aplicații web trebuie să accepte o anumită formă de autentificare și autorizare, iar OAuth se potrivește facturii aici.

Pentru citirea ulterioară

  • OAuth și Drumul spre iad
  • OAuth - o introducere
  • RFC 5849 - OAuth1.0 spec
  • RFC 6749 - OAuth2.0 spec
Cod