OAuth 2.0 - The Good, The Bad & The Ugly

I en verden dominert av sosiale medier, er det vanskelig å ikke komme over en klientprogram som du har brukt til å få tilgang til begrensede ressurser på en annen server, for eksempel kan du ha brukt et web-basert program (som NY Times) for å dele en interessant nyhetsartikkel på Facebook-veggen din eller tweet om det. Du kan også ha brukt Quoras iPhone-app som får tilgang til Facebook eller Google + -profilen din, og tilpasser resultatene basert på profildataene dine, for eksempel å foreslå å legge til / invitere andre brukere til Quora, basert på vennelisten din. Spørsmålet er hvordan disse programmene får tilgang til Facebook, Twitter eller Google+ kontoer, og hvordan kan de få tilgang til dine konfidensielle data? Før de kan gjøre det, må de presentere noen form for godkjenningsinformasjon og autorisasjonstilskudd til ressursserveren.


Introduksjon til OAuth 2.0

OAuth beskrives ofte som en valetnøkkel for Internett.

Nå ville det egentlig være uncool å dele din Facebook- eller Google-legitimasjon med et tredjepartsklientprogram som bare trenger å vite om dine venner, da det ikke bare gir appen ubegrenset og uønsket tilgang til kontoen din, men den har også den iboende svakheten som er knyttet til passordene. Dette er hvor OAuth kommer til spill, da det skisserer en tilgangsdelegasjon / autorisasjonsramme som kan brukes uten at det må deles passord. Av denne grunn blir OAuth ofte beskrevet som en betjentnøkkel for Internett. Det kan betraktes som en spesialnøkkel som gir tilgang til begrensede funksjoner og for en begrenset periode uten å gi full kontroll, akkurat som valetasten for en bil tillater at parkeringsvakt kjører bilen i kort avstand, og blokkerer tilgang til bagasjen og ombord mobiltelefonen.

OAuth er imidlertid ikke et nytt konsept, men en standardisering og kombinert visdom av mange veletablerte protokoller. Det er også verdt å merke seg at OAuth ikke bare er begrenset til sosiale medier, men gir en standardisert måte å dele informasjon sikkert mellom ulike typer applikasjoner som avslører API-ene sine til andre applikasjoner. OAuth 2.0 har en helt ny prosa og er ikke bakoverkompatibel med forgjengerspesifikasjonen. Når det er sagt, vil det være bra å først dekke noen grunnleggende OAuth2.0-ordforråd før du drar i ytterligere detaljer.

  • Ressursinnehaver : Et foretak som kan gi tilgang til en beskyttet ressurs. Mesteparten av tiden er det en sluttbruker.
  • Klient : En applikasjon som gjør beskyttede ressursforespørsler på vegne av ressurseier og med fullmakt. Det kan være en serverbasert, mobil (innfødt) eller et skrivebordsprogram.
  • Ressursserver : Serveren serverer de beskyttede ressursene, som er i stand til å akseptere og svare på beskyttede ressursforespørsler.
  • Autorisasjonsserver : Serveren som gir tilgang til tilskudd / tokens til klienten etter at du har godkjent ressurseier og godkjent.
  • Tilgangstoken : Tilgangstokenetter er legitimasjonsbeskrivelser presentert av klienten til ressursserveren for å få tilgang til beskyttede ressurser. Det er normalt en streng som består av et bestemt omfang, levetid og andre tilgangsfunksjoner, og det kan selv inneholde autorisasjonsinformasjonen på en kontrollerbar måte.
  • Refresh Token : Selv om det ikke er mandat fra spesifikasjonen, har tilgangstoken helst en utløpsdato som kan vare hvor som helst fra noen få minutter til flere timer. Når en tilgangstoken er utløpt, kan klienten be om autorisasjonsserveren å utstede et nytt tilgangstoken ved hjelp av oppdateringstoken utstedt av autorisasjonsserveren.

Hva er galt med OAuth 1.0?

OAuth 1.0s store ulempe var den innebygde kompleksiteten som trengs for å implementere spesifikasjonen.

Ingenting egentlig! Twitter jobber fortsatt perfekt med OAuth 1.0 og har nettopp startet å støtte en liten del av 2.0-spesifikasjonen. OAuth 1.0 var en godt gjennomtenkt spesifikasjon, og det tillot utveksling av hemmelig informasjon sikkert uten overhead pålagt av SSL. Grunnen til at vi trengte en revolusjon var hovedsakelig basert på kompleksiteten som ble møtt i implementeringen av spesifikasjonen. Følgende er noen områder der OAuth 1.0 ikke kunne imponere:

  • Signering hver forespørsel : Å ha klienten generere signaturer på hver API-forespørsel og validere dem på serveren hver gang en forespørsel er mottatt, viste seg å være et stort tilbakeslag for utviklere, da de måtte analysere, kode og sortere parametrene før du foretar en forespørsel. OAuth 2.0 fjernet denne kompleksiteten ved ganske enkelt å sende tokens over SSL, og løse det samme problemet på nettverksnivå. Ingen signaturer kreves med OAuth 2.0.
  • Adressering av innfødte applikasjoner : Med utviklingen av innfødte applikasjoner for mobile enheter virket den nettbaserte strømmen av OAuth 1.0 ineffektiv, som innebar bruk av brukeragenter som en nettleser. OAuth 2.0 har innkvartert flere strømmer som er spesielt egnet for innfødte applikasjoner.
  • Klare adskillelse av roller : OAuth 2.0 gir den nødvendige tilskillingen av roller for autorisasjonsserveren som autentiserer og autoriserer klienten, og at i ressursserverhåndterings-API-samtaler skal du få tilgang til begrensede ressurser.

OAuth 2.0 i Dybde

Før du starter protokollen, må klienten registrere deg hos autorisasjonsserveren ved å gi sin klienttype, omadresseringsadressen (der den vil at autorisasjonsserveren skal omdirigere til ressursinnehaveren gir eller avviser tilgangen) og annen informasjon som kreves av serveren og i sin tur får en klientidentifikator (client_id) og klienthemmelighet (client_secret). Denne prosessen er kjent som kunderegistrering. Etter registrering kan klienten vedta en av følgende strømmer for å kommunisere med serveren.

Ulike OAuth-strømmer

OAuth 2.0 gir omtrent fem nye strømmer til bordet og gir utviklere fleksibiliteten til å implementere noen av dem, avhengig av hvilken type klient som er involvert:

  • User-Agent Flow : Egnet for klienter som vanligvis implementeres i brukeragenter (for eksempel klienter som kjører inne i en nettleser) ved hjelp av et skriptspråk som JavaScript. Mest brukt av innfødte programmer for mobil eller skrivebord, bruk av den innebygde eller eksterne nettleseren som brukeragent for autorisasjon, og bruker den Implisitt Grant autorisasjon.
  • Web Server Flow : Dette gjør bruk av Godkjennelseskoden bevilg og er en omdirigasjonsbasert flyt som krever samhandling med sluttbrukerens brukeragent. Dermed er det best egnet for klienter som er en del av web-serverbaserte applikasjoner, som vanligvis nås via en nettleser.
  • Brukernavn og passordflyt : Brukes kun når det er høy tillit mellom klienten og ressurseier og når andre strømmer ikke er levedyktige, da det innebærer overføring av ressursens eierens legitimasjon. Eksempler på klienter kan være et operativsystem eller et svært privilegert program. Dette kan også brukes til å migrere eksisterende klienter ved hjelp av HTTP Basic eller Digest Authentication-ordninger til OAuth ved å konvertere de lagrede legitimasjonene til en tilgangstoken.
  • Assertion Flow : Din klient kan presentere en påstand som SAML Assertion til autorisasjonsserveren i bytte for en tilgangstoken.
  • Client Credentials Flow : OAuth brukes hovedsakelig for delegert tilgang, men det er tilfeller der kunden eier ressursen eller allerede har fått den delegerte tilgangen utenfor en typisk OAuth-flyt. Her bytter du bare kundeopplysningene for et tilgangstoken.

Å diskutere hver strøm i detalj vil være utenfor rammen av denne artikkelen, og jeg vil helst anbefale å lese spesifikasjonen for dyp flytinformasjon. Men for å få en følelse for hva som skjer, la oss grave dypere inn i en av de mest brukte og støttede strømmene: Web Server Flow.

Webserverstrømmen

Siden dette er en omadresseringsbasert flyt, må klienten kunne kommunisere med ressurseierens brukeragent (som i de fleste tilfeller er en nettleser) og er derfor typisk egnet for et webprogram. Det nedenstående diagrammet er et fugleperspektiv av hvordan sluttbrukeren (eller ressurseier) bruker klientprogrammet (webserverbasert applikasjon i dette tilfellet) for å godkjenne og autorisere med autorisasjonsserveren for å få tilgang til ressursene som er beskyttet av ressursserveren.


Godkjen og autoriser klienten

Klienten, på vegne av ressurseier, initierer strømmen ved å omdirigere til autorisasjonsendepunktet med en response_type-parameter som kode, en klientidentifikator, som oppnås under klientregistrering, en omadresseringsadresse, et ønsket omfang (valgfritt) og en lokal tilstand (hvis noen). For å få en følelse av hvordan det egentlig virker, her er et skjermbilde av hvordan en typisk forespørsel / respons vil se ut:


Dette presenterer vanligvis ressurseier med et webgrensesnitt, hvor eieren kan autentisere og kontrollere hva alle tillatelser klientappen kan bruke på eierens vegne.


Forutsatt at ressurseier gir tilgang til klienten, omstiller autorisasjonsserveren brukeragenten tilbake til klienten ved hjelp av omadresseringsadressen som ble oppgitt tidligere, sammen med autorisasjonskoden som vist ved svaret nedenfor.


Exchange Authorization Code for Tokens

Klienten da innlegg til et annet autorisasjonsendepunkt og sender autorisasjonskoden mottatt i det tidligere trinnet, sammen med omadresseringsadressen, klientidentifikatoren og hemmelig, oppnådd under klientregistrering, og en grant_type-parameter må settes som Godkjennelseskoden.


Serveren validerer deretter autorisasjonskoden og verifiserer at omadresseringsadressen er den samme som den var i det tidligere trinnet. Hvis det lykkes, svarer serveren tilbake med et tilgangstoken og eventuelt et oppdateringstoken.


Be om begrensede ressurser ved hjelp av tilgangstegn

Klienten kan nå forbruke APIene som leveres av implementeringen, og kan spørre ressursserveren for en begrenset ressurs ved å passere tilgangstokenet i autorisasjonsoverskriften til forespørselen. En prøve CURL-forespørsel til Googles Blogger-API for å få en blogg, gitt sin identifikator, ville se slik ut:

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

Merk at vi har lagt til Tilgangstoken som et autorisasjonsoverskrift i forespørselen, og også rømt token ved å inkludere den i enkelt anførselstegn, da token kan inneholde spesialtegn. Husk at rømming av tilgangstoken bare kreves ved bruk av krøll. Det resulterer i å sende følgende forespørsel:


Resursserveren verifiserer deretter de bestått legitimasjonene (tilgangstoken), og hvis det lykkes, svarer den tilbake med den forespurte informasjonen.


Disse eksemplene er courtesy of OAuth2.0 Playground og er typisk for hvordan Google implementerer spesifikasjonen. Forskjeller kan observeres når man prøver samme strøm med andre leverandører (som Facebook eller Salesforce), og dette er hvor interoperabilitetsproblemer kryper inn, som vi diskuterer litt senere.

Forfriskende tilgangstoken

Selv om det ikke er mandat av spesifikasjonen, men vanligvis er tilgangstegnene kortvarige og kommer med en utløpstid. Så når et tilgangstoken er utløpt, sender klienten oppdateringstoken til autorisasjonsserveren, sammen med klientidentifikatoren og hemmelig, og en grant_type-parameter som refresh_token.


Autorisasjonsserveren svarer deretter tilbake med den nye verdien for tilgangstokenet.


Selv om det finnes en mekanisme for å tilbakekalle oppfriskningstoken utstedt, men normalt oppfrisker token lever for alltid og må beskyttes og behandles som en hemmelig verdi.


Hva er galt med OAuth 2.0?

The Good Stuff

OAuth 2.0 er definitivt en forbedring i forhold til sin arcane forgjenger. Forekomster av utviklerfellesskapet som falter mens du implementerer signaturene på 1.0, er ikke ukjent. OAuth 2.0 tilbyr også flere nye tildelingstyper, som kan brukes til å støtte mange brukssaker som innfødte applikasjoner, men USP av denne spesifikasjonen er enkelhet over den forrige versjonen.

De dårlige delene

Det er noen løse ender i spesifikasjonen, da det ikke klarer å definere noen få nødvendige komponenter eller overlater dem til implementeringene for å bestemme, for eksempel:

Løse ender i OAuth 2.0-spesifikasjonen vil trolig gi et bredt spekter av ikke-interoperable implementeringer.

  • Interoperabilitet: Å legge til for mange utvidelsespunkter i spesifikasjonen resulterte i implementeringer som ikke er kompatible med hverandre. Det betyr at du ikke kan håpe å skrive et generisk stykke kode som bruker Endpoint Discovery å vite om sluttpunktene som tilbys av de ulike implementasjonene og samhandle med dem, heller du må skrive separate kodestykker for Facebook, Google, Salesforce og så videre. Selv spesifikasjonen innrømmer denne feilen som en ansvarsfraskrivelse.
  • Kortlevede Tokens: Spesifikasjonen forutsetter ikke levetiden og omfanget av de utstedte tokens. Gjennomføringen er fri for at et token lever for alltid. Selv om de fleste implementasjonene gir oss kortvarige tilgangstokener og et oppdateringstegn, som kan brukes til å få en ny tilgangstoken.
  • Sikkerhet: Spesifikasjonen bare "anbefaler" bruken av SSL / TLS mens du sender tokens i ren tekst over ledningen. Selv om alle viktige gjennomføringene har gjort det nødvendig å ha sikre autorisasjonsendepunkter, krever det at klienten må ha en sikker omadresseringsadresse, ellers vil det være altfor lett for en angriper å avlyse på kommunikasjonen og dechiffrere tokens.

The Ugly Spat

Det tok IETF om 31 utkastsversjoner og oppsigelsen av hovedforfatteren / utvikleren Eran Hammer fra komiteen for endelig å publisere spesifikasjonen. Eran utløst en kontrovers ved å ringe spec "en dårlig protokoll og et tilfelle av død med tusen kutt". Ifølge ham var bruken av bærer tokens (sende tokens over SSL uten å signere dem eller annen verifisering) over brukeren av signaturer (eller MAC-Tokens), brukt i OAuth 1.0 for å signere forespørselen, et dårlig trekk og et resultat av deling av interesser mellom Internett og bedriftssamfunn.


Avsluttende bemerkninger

Spesifikasjonen forlater sikkert mange utvidelsespunkter i åpen, noe som resulterer i implementeringer som introduserer sine egne parametere, i tillegg til hva spesifikasjonen allerede definerer, og sørger for at implementeringer fra forskjellige tilbydere ikke kan interoperere med hverandre. Men å gå med popularitets- og adopsjonsgraden av dette rammeverket, med alle store spillerne i byen (Google, Twitter, Facebook, Salesforce, Foursquare, Github etc.) implementere og tilpasse det slik det passer dem, er OAuth langt fra å være en feil . Faktisk må enhver webapplikasjon som planlegger å avsløre API-ene sine til andre webapplikasjoner, støtte noen form for godkjenning og autorisasjon, og OAuth passer til regningen her.

For videre lesing

  • OAuth og veien til helvete
  • OAuth - En introduksjon
  • RFC 5849 - OAuth1.0 spesifikasjon
  • RFC 6749 - OAuth2.0 spesifikasjon