Was ist der Unterschied zwischen dem OAuth-Autorisierungscode und impliziten Workflows? Wann sollte jeder verwendet werden?


164

OAuth 2.0 verfügt über mehrere Workflows. Ich habe ein paar Fragen zu den beiden.

  1. Ablauf des Autorisierungscodes - Der Benutzer meldet sich über die Client-App an. Der Autorisierungsserver gibt einen Autorisierungscode an die App zurück. Die App tauscht dann den Autorisierungscode gegen das Zugriffstoken aus.
  2. Impliziter Grant-Flow - Der Benutzer meldet sich über die Client-App an. Der Autorisierungsserver stellt ein Zugriffstoken direkt an die Client-App aus.

Was ist der Unterschied zwischen den beiden Ansätzen in Bezug auf die Sicherheit? Welches ist sicherer und warum?

Ich sehe keinen Grund, warum ein zusätzlicher Schritt (Austauschautorisierungscode für Token) in einem Workflow hinzugefügt wird, wenn der Server direkt ein Zugriffstoken ausstellen kann.

Verschiedene Websites geben an, dass der Autorisierungscode-Fluss verwendet wird, wenn die Client-App die Anmeldeinformationen sicher aufbewahren kann. Warum?


Antworten:


204

Dies access_tokenist, was Sie benötigen, um eine geschützte Ressource (eine API) aufzurufen. Im Ablauf des Autorisierungscodes gibt es zwei Schritte, um ihn abzurufen:

  1. Der Benutzer muss sich authentifizieren und eine codean den API-Konsumenten zurückgeben (als "Client" bezeichnet).
  2. Der "Client" der API (normalerweise Ihr Webserver) tauscht das codein # 1 erhaltene gegen ein aus access_tokenund authentifiziert sich mit einem client_idundclient_secret
  3. Es kann dann die API mit dem aufrufen access_token.

Es gibt also eine doppelte Überprüfung: Der Benutzer, dem die Ressourcen gehören, die über eine API aufgetaucht sind, und der Client, der die API verwendet (z. B. eine Web-App). Beide sind für die Gewährung des Zugriffs validiert. Beachten Sie die "Autorisierung" von OAuth hier: Der Benutzer gewährt codeeiner App Zugriff auf seine Ressource (über die nach der Authentifizierung zurückgegebene), die App erhält eine access_tokenund ruft im Namen des Benutzers auf.

Im impliziten Ablauf wird Schritt 2 weggelassen. Nach der Benutzerauthentifizierung wird ein access_tokendirekt zurückgegeben, mit dem Sie auf die Ressource zugreifen können. Die API weiß nicht, wer diese API aufruft. Jeder mit der access_tokenDose, während im vorherigen Beispiel nur die Web-App (die Interna sind normalerweise für niemanden zugänglich).

Der implizite Fluss wird normalerweise in Szenarien verwendet, in denen gespeichert wird client id und client secretwird nicht empfohlen (ein Gerät zum Beispiel, obwohl viele es tut sowieso). Das bedeutet der Haftungsausschluss. Die Benutzer haben Zugriff auf den Clientcode und können daher die Anmeldeinformationen abrufen und sich als Ressourcenclients ausgeben. Im impliziten Fluss sind alle Daten flüchtig und es ist nichts in der App gespeichert.


Vielen Dank für Ihre Erklärung, aber ich verstehe nicht, warum wir einen weiteren Ablauf für den Autorisierungscode benötigen. Wir können dasselbe Ergebnis auf dem Server durch impliziten Fluss (access_token) und ein Aktualisierungstoken erreichen. Es sieht so aus, als ob die einzige Sicherheitsüberlegung des impliziten Flusses darin besteht, dass access_code eine kurze Lebensdauer haben sollte, damit es nicht von Server zu Server verwendet werden kann. OK, aber das Aktualisierungstoken löst dieses Problem. Warum sollten wir einen auth_code-Fluss verwenden und access_token von diesem auf dem Server anfordern, um access_code zu erhalten?
Mohammad Nikravan

Nun ... so funktioniert das Protokoll. Vielleicht möchten Sie die Spezifikationsbedrohungsanalyse lesen, um eine detailliertere Referenz zu den Sicherheitsvorteilen des einen und des anderen zu erhalten.
Eugenio Pace

Ich weiß, dass die ursprüngliche Antwort älter als 5 Jahre ist, aber dies ist die einfachste und sauberste Erklärung, die ich je gelesen habe. Vielen Dank, dass Sie @ EugenioPace
Taha Ahmad

1
@ Madnik7G Der Grund ist orthogonal zu dem, was diese Antwort erklärt (wunderschön): Möglicherweise ist ein Dritter beteiligt. Der gesamte Ablauf wird von einem Benutzeragenten (z. B. dem Browser) orchestriert, aber am Ende kommuniziert der Autorisierungsserver (z. B. "Mit Facebook anmelden") direkt mit dem Client (z. B. Ihrer serverseitigen BFF) Greifen Sie letztendlich auf die Ressource zu, sodass der Benutzeragent niemals direkten Zugriff hat.
Daniel Langdon

Vielen Dank! Ja, es finden 3 Kommunikationen statt: der Browser und der AS 9e.g. Facebook). Das ist die /authorizeBitte. Der Browser und die Website, die versuchen, die API (auch als Client bezeichnet) aufzurufen. Dies ist das redirect_uri+, codedas der AS nach erfolgreicher Authentifizierung zurückgibt. Schließlich ruft der Client den AS hinter den Kulissen an und tauscht ihn codegegen einen aus access_token. Dies ist die token endpointin der Literatur. Im Allgemeinen ruft der AS niemals jemanden an. Es antwortet immer.
Eugenio Pace

52

Ich werde hier etwas hinzufügen, von dem ich glaube, dass es in den obigen Antworten nicht klar ist:

  • Der Authorization-Code-Flow ermöglicht, dass das endgültige Zugriffstoken niemals erreicht wird und niemals mit dem Browser / der App auf dem Computer gespeichert wird . Der temporäre Autorisierungscode wird dem Computer mit dem Browser / der App übergeben, der dann an einen Server gesendet wird. Der Server kann es dann mit einem Vollzugriffstoken austauschen und Zugriff auf APIs usw. haben. Der Benutzer mit dem Browser erhält Zugriff auf die API nur über den Server mit dem Token.
  • Der implizite Datenfluss kann nur zwei Parteien betreffen, und das endgültige Zugriffstoken wird mit dem Browser / der App auf dem Client gespeichert. Wenn dieser Browser / diese App kompromittiert ist, ist auch ihr Auth-Token gefährdet, was gefährlich sein kann.

tl; dr verwendet keinen impliziten Fluss , wenn Sie nicht dem Benutzer Maschine zu halten , Tokens vertrauen , aber Sie tun Ihren eigenen Servern vertrauen.


12
Betreff: Der Benutzer mit dem Browser erhält nur über den Server mit dem Token Zugriff auf die API. Der Server muss jedoch etwas an den Browser senden , damit die eingehenden Anforderungen dem Token zugeordnet werden können, das serverseitig gespeichert wird. Ein Keks, wenn Sie möchten. Wenn der Server das Token nicht an den im Browser ausgeführten JS überträgt, muss er etwas anderes übertragen, das der (Browser-) Client an den Server übergeben muss, damit der Server im Namen des jeweiligen Clients handeln kann.
Cheeso

Ja, ein Keks. Daher sollten Sie Ihren Server und Ihren Browser-Client so einrichten, dass er vor Fälschungen von standortübergreifenden Anforderungen geschützt ist.
Marcel

@Marcel Ich würde gerne wissen, dass, sobald wir den Code erhalten haben, wie und wo der Austausch stattfindet, um den tatsächlichen access_tokenmit Hilfe von zu erhalten authorization code.
Chirag Soni

14

Der Unterschied zwischen beiden ist:

  1. Im impliziten Ablauf wird das Token direkt über die Umleitungs-URL mit dem Zeichen "#" zurückgegeben. Dies wird hauptsächlich in Javascript-Clients oder mobilen Anwendungen verwendet, die keine eigene Serverseite haben, und der Client muss in einigen Implementierungen sein Geheimnis nicht angeben .

  2. Im Autorisierungscode-Fluss wird Code mit "?" Zurückgegeben. Um von der Serverseite lesbar zu sein, muss die Serverseite diesmal das Client-Geheimnis für die Token-URL bereitstellen, um das Token als JSON-Objekt vom Autorisierungsserver abzurufen. Es wird verwendet, wenn Sie einen Anwendungsserver haben, der dies handhaben und Benutzertoken mit seinem Profil auf seinem eigenen System speichern kann, und wird hauptsächlich für gängige mobile Anwendungen verwendet.

Es hängt also von der Art Ihrer Client-Anwendung ab, welcher weitere sichere "Autorisierungscode", da er das Geheimnis auf dem Client anfordert, und das Token zwischen Autorisierungsserver und Client-Anwendung über eine sehr gesicherte Verbindung gesendet werden können, und der Autorisierungsanbieter kann dies Beschränken Sie einige Clients darauf, nur "Autorisierungscode" zu verwenden, und lassen Sie Implicit nicht zu


Der Autorisierungscode wird für Facebook 10 Minuten lang auf der Serverseite gespeichert. Dies wurde in ihrer Änderung vom 5. Dezember 2012 veröffentlicht. Meine Frage ist hauptsächlich, was ist der Unterschied zwischen den beiden in Bezug auf Sicherheit / Leistung. Ich weiß, was beide Flows tun - aber was ist der Vorteil der Verwendung von Autorisierungscode - und fügt dem Workflow einen weiteren Schritt hinzu.
Divyanshm

Wenn das Token nicht direkt an die Benutzeranwendung gesendet wird, ist die Verbindung zwischen der Clientanwendung und dem Autorisierungsserver für den Benutzer verborgen, und wie bereits erwähnt, kann es sich um einen sehr sicheren Kanal handeln, der nicht mit dem vom Benutzer zur Clientanwendung identisch ist.
Bassem Reda Zohdy

Leistung im Autorisierungscode Sie haben den Authentifizierungsserver zweimal aufgerufen, sodass dies mehr Zeit in Anspruch nimmt. Außerdem speichert der Client-Server das Benutzertoken und dies erhöht auch die Zeit.
Bassem Reda Zohdy

2
Ohh ok! Ich hätte das vielleicht übersehen. Der Autorisierungscodefluss sollte also grundsätzlich von Systemen verwendet werden, bei denen ein ganzer Server ein Client ist - der Browser stellt die Anforderung und erhält den Code. Der Code wird an den Client-Server gesendet, der eine sichere Verbindung zum Ressourcenserver herstellt. Verstehe ich es richtig Das Zugriffstoken erreicht nie den Computer des Endbenutzers?
Divyanshm

1
Das Zugriffstoken erreicht nie den Computer des Endbenutzers? Ja, es ist mit Ihrem Profil mit dem Clientanwendungsserver verknüpft.
Bassem Reda Zohdy

4

Die implizite Erteilung ähnelt der Erteilung des Autorisierungscodes mit zwei unterschiedlichen Unterschieden.

Es ist für Benutzeragenten-basierte Clients (z. B. einseitige Web-Apps) vorgesehen, die einen Client nicht geheim halten können, da der gesamte Anwendungscode und Speicher leicht zugänglich sind.

Zweitens gibt der Autorisierungsserver anstelle des Autorisierungsservers, der einen Autorisierungscode zurückgibt, der gegen ein Zugriffstoken ausgetauscht wird, ein Zugriffstoken zurück.

Details finden Sie hier http://oauth2.thephpleague.com/authorization-server/which-grant/


1
Vielen Dank für diesen Link, der mir geholfen hat, den Unterschied zwischen den einzelnen Zuschusstypen und dem Zeitpunkt der Auswahl zu verstehen.
François POYER

3

Impliziter Fluss

Vorteile

  • Am einfachsten zu implementieren

Nachteile

  • Zugriffstoken, die für den Browser sichtbar sind
  • Die Herkunft der Zugriffstoken kann nicht bestimmt werden
  • Zugriffstoken können nicht ablaufen (gemäß Google-Richtlinie)

Ablauf des Autorisierungscodes

Vorteile

  • Am sichersten
  • Zugriffstoken und Aktualisierungstoken können nur erstellt werden, wenn ein gemeinsames Geheimnis bekannt ist
  • Kann mit neuen Sicherheits- und UX-Funktionen erweitert werden, sobald diese verfügbar sind

Nachteile

  • Es müssen mehrere Authentifizierungsendpunkte implementiert werden

Zitat: https://developers.google.com/actions/develop/identity/oauth2-overview#supported_oauth_20_flows


2

Lassen Sie mich die Punkte zusammenfassen, die ich aus den obigen Antworten gelernt habe, und einige meiner eigenen Erkenntnisse hinzufügen.

Ablauf des Autorisierungscodes !!!

  • Wenn Sie einen Webanwendungsserver haben, der als OAuth-Client fungiert
  • Wenn Sie einen langlebigen Zugang haben möchten
  • Wenn Sie offline auf Daten zugreifen möchten
  • wenn Sie für API-Anrufe verantwortlich sind, die Ihre App tätigt
  • Wenn Sie Ihr OAuth-Token nicht verlieren möchten
  • Wenn Sie nicht möchten, dass Ihre Anwendung jedes Mal den Autorisierungsfluss durchläuft, wenn sie Zugriff auf Daten benötigt. ANMERKUNG: Der implizite Grant-Flow enthält kein Aktualisierungstoken. Wenn der Autorisierungsserver regelmäßig Zugriffstoken abläuft, muss Ihre Anwendung den Autorisierungsfluss immer dann ausführen, wenn sie Zugriff benötigt.

Impliziter Grant Flow !!!

  • Wenn Sie keinen Webanwendungsserver als OAuth-Client haben
  • Wenn Sie keinen langlebigen Zugriff benötigen, dh nur vorübergehenden Zugriff auf Daten erforderlich ist.
  • Wenn Sie dem Browser vertrauen, in dem Ihre App ausgeführt wird, und nur begrenzte Bedenken bestehen, dass das Zugriffstoken an nicht vertrauenswürdige Benutzer weitergegeben wird.

2

Welches ist sicherer und warum?

Beide sind sicher, dies hängt von der Umgebung ab, in der Sie sie verwenden.

Ich sehe keinen Grund, warum ein zusätzlicher Schritt (Austauschautorisierungscode für Token) in einem Workflow hinzugefügt wird, wenn der Server direkt ein Zugriffstoken ausstellen kann.

Es ist einfach. Ihr Kunde ist nicht sicher. Lassen Sie es uns im Detail sehen.

Stellen Sie sich vor, Sie entwickeln eine Anwendung gegen Instagram API, registrieren Sie Ihre APP bei Instagramund definieren API'sSie , welche Sie benötigen. Instagramwird Sie mit client_idund versorgenclient_secrect

Auf Ihrer Website haben Sie einen Link eingerichtet, der besagt. "Komm und benutze meine Anwendung". Wenn Sie darauf klicken, sollte Ihre Webanwendung zwei Anrufe tätigen Instagram API.

FirstSenden Sie eine Anfrage an Instagram Authentication Servermit den folgenden Parametern.

1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token. 

Sie senden nichtclient_secret , Sie konnten dem Client nicht vertrauen (dem Benutzer und / oder seinem Browser, die versuchen, Ihre Anwendung zu verwenden). Der Client kann die URL oder das Java-Skript sehen und Ihre client_secrectleicht finden. Deshalb brauchen Sie einen weiteren Schritt.

Sie erhalten ein codeund state. Das codehier ist temporaryund wird nirgendwo gespeichert.

Dann secondrufen Sie an Instagram API(von Ihrem Server)

 1. `grant_type` with the value of `authorization_code`
 2. `client_id` with the client identifier
 3. `client_secret` with the client secret
 4. `redirect_uri` with the same redirect URI the user was redirect back to
 5. `code` which we have already received.

Da der Anruf von unserem Server aus getätigt wird, können wir sicher verwenden client_secret(was zeigt, wie wir sind), mit codewelchen Shows der Benutzer die client_idNutzung der Ressource gewährt hat .

Als Antwort werden wir haben access_token


1

Aus praktischer Sicht (was ich verstanden habe) ist der Hauptgrund für den Authz-Code-Fluss:

  1. Unterstützung für Aktualisierungstoken (langfristiger Zugriff durch Apps im Namen des Benutzers), nicht implizit unterstützt: siehe: https://tools.ietf.org/html/rfc6749#section-4.2
  2. Support für die Einwilligungsseite, auf der der Ressourcenbesitzer steuern kann, welcher Zugriff bereitgestellt werden soll (Art der Berechtigungs- / Autorisierungsseite, die Sie in Google sehen). Gleiches gibt es nicht implizit. Siehe Abschnitt: https://tools.ietf.org/html/rfc6749#section-4.1 , Punkt (B)

"Der Autorisierungsserver authentifiziert den Ressourcenbesitzer (über den Benutzeragenten) und stellt fest, ob der Ressourcenbesitzer die Zugriffsanforderung des Clients gewährt oder verweigert."

Darüber hinaus können Apps mithilfe von Aktualisierungstoken langfristig auf Benutzerdaten zugreifen.


0

Es scheint zwei wichtige Punkte zu geben, die bisher nicht erörtert wurden und die erklären, warum der Umweg im Berechtigungscode-Gewährungstyp die Sicherheit erhöht.

Kurzgeschichte : Der Berechtigungscode-Gewährungstyp speichert vertrauliche Informationen aus dem Browserverlauf, und die Übertragung des Tokens hängt nur vom HTTPS-Schutz des Autorisierungsservers ab.

Längere Version:

Im Folgenden werde ich mich an die im RFC definierte OAuth 2-Terminologie halten (es ist ein schnelles Lesen): Ressourcenserver , Client , Autorisierungsserver , Ressourceneigentümer .

Stellen Sie sich vor, Sie möchten, dass eine Drittanbieter-App (= Client) auf bestimmte Daten Ihres Google-Kontos (= Ressourcenserver) zugreift. Nehmen wir einfach an, Google verwendet OAuth 2. Sie sind der Ressourcenbesitzer für das Google-Konto, betreiben jedoch derzeit die Drittanbieter-App.

Zunächst öffnet der Client einen Browser, um Sie an die sichere URL des Google-Autorisierungsservers zu senden. Anschließend genehmigen Sie die Zugriffsanforderung, und der Autorisierungsserver sendet Sie mit dem Autorisierungscode in der Abfragezeichenfolge an die zuvor angegebene Weiterleitungs-URL des Clients zurück. Nun zu den beiden wichtigsten Punkten:

  1. Die URL dieser Weiterleitung landet im Browserverlauf . Wir wollen hier also kein langlebiges, direkt verwendbares Zugriffstoken. Der kurzlebige Autorisierungscode ist in der Geschichte weniger gefährlich. Beachten Sie, dass der implizite Grant - Typ ist das Token in der Geschichte setzen.
  2. Die Sicherheit dieser Weiterleitung hängt vom HTTPS-Zertifikat des Clients ab , nicht vom Google-Zertifikat. Wir erhalten also die Übertragungssicherheit des Clients als zusätzlichen Angriffsvektor (Damit dies unvermeidbar ist, muss der Client kein JavaScript sein. Da wir sonst den Autorisierungscode über eine Fragment-URL übertragen könnten, würde der Code nicht über das Netzwerk übertragen. Dies mag der Grund sein , warum Implizite Grant Typ, das tut ein Fragment URL verwenden, verwendet für JavaScript Kunden empfohlen werden, auch wenn das nicht mehr so.)

Mit dem Berechtigungscode-Gewährungstyp wird das Token schließlich durch einen Aufruf des Clients an den Autorisierungsserver abgerufen, wobei die Übertragungssicherheit nur vom Autorisierungsserver und nicht vom Client abhängt .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.