OAuth 2.0 - Das Gute, das Schlechte und das Hässliche
German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)
In einer von sozialen Medien dominierten Welt ist es schwierig, nicht auf eine Clientanwendung zu stoßen, mit der Sie auf eingeschränkte Ressourcen auf einem anderen Server zugegriffen haben. Beispielsweise haben Sie möglicherweise eine webbasierte Anwendung (wie die NY Times) verwendet, um eine zu teilen interessanter Nachrichtenartikel auf Ihrer Facebook-Pinnwand oder Tweet darüber. Möglicherweise haben Sie auch die iPhone-App von Quora verwendet, die auf Ihr Facebook- oder Google+ Profil zugreift und die Ergebnisse basierend auf Ihren Profildaten anpasst. Sie können beispielsweise vorschlagen, andere Benutzer basierend auf Ihrer Freundesliste zu Quora hinzuzufügen oder einzuladen. Die Frage ist, wie diese Anwendungen Zugriff auf Ihre Facebook-, Twitter- oder Google+ Konten erhalten und wie sie auf Ihre vertraulichen Daten zugreifen können. Bevor sie dies tun können, müssen sie dem Ressourcenserver irgendeine Form von Authentifizierungsdaten und Berechtigungsberechtigungen vorlegen.
Einführung in OAuth 2.0
OAuth wird häufig als Valet-Schlüssel für das Web beschrieben.
Jetzt wäre es wirklich unangenehm, Ihre Facebook- oder Google-Anmeldeinformationen mit einer Drittanbieter-Clientanwendung zu teilen, die nur über Ihre Freunde Bescheid wissen muss, da die App dadurch nicht nur unbegrenzten und unerwünschten Zugriff auf Ihr Konto erhält, sondern auch über die inhärente Schwäche im Zusammenhang mit Passwörtern. Hier kommt OAuth ins Spiel, da es ein Framework für die Zugriffsdelegierung / -autorisierung beschreibt, das verwendet werden kann, ohne dass Kennwörter gemeinsam genutzt werden müssen. Aus diesem Grund wird OAuth häufig als Valet-Schlüssel für das Web beschrieben. Es kann als ein spezieller Schlüssel betrachtet werden, der den Zugriff auf eingeschränkte Funktionen und für einen begrenzten Zeitraum ermöglicht, ohne die volle Kontrolle zu verlieren, ebenso wie der Parkservice-Schlüssel für ein Auto es dem Parkwächter ermöglicht, das Auto für eine kurze Strecke zu fahren und zu blockieren Zugang zum Kofferraum und zum Bordhandy.
OAuth ist jedoch kein neues Konzept, sondern eine Standardisierung und kombinierte Weisheit vieler gut etablierter Protokolle. OAuth ist jedoch kein neues Konzept, sondern eine Standardisierung und kombinierte Weisheit vieler gut etablierter Protokolle. OAuth 2.0 hat eine völlig neue Prosa und ist nicht abwärtskompatibel mit seiner Vorgängerspezifikation. Trotzdem wäre es gut, zuerst einige grundlegende OAuth2.0-Vokabeln zu behandeln, bevor Sie auf weitere Details eingehen.
- Ressourcenbesitzer: Eine Entität, die Zugriff auf eine geschützte Ressource gewähren kann. Meistens ist es ein Endbenutzer.
- Client: Eine Anwendung, die im Namen des Ressourcenbesitzers und mit seiner Autorisierung geschützte Ressourcenanforderungen stellt. Das kann eine serverbasierte, mobile (native) oder eine Desktop-Anwendung sein.
- Ressourcenserver: Der Server, auf dem die geschützten Ressourcen gehostet werden und der geschützte Ressourcenanforderungen annehmen und darauf reagieren kann.
- Autorisierungsserver: Der Server, der dem Client nach erfolgreicher Authentifizierung des Ressourcenbesitzers und Erhalt der Autorisierung Zugriffsberechtigungen/Token ausstellt.
- Access Token: Access Token sind Anmeldeinformationen, die der Client dem Ressourcenserver für den Zugriff auf geschützte Ressourcen vorlegt. Normalerweise handelt es sich um eine Zeichenfolge, die aus einem bestimmten Bereich, einer bestimmten Lebensdauer und anderen Zugriffsattributen besteht und die Berechtigungsinformationen möglicherweise auf überprüfbare Weise selbst enthält.
- Aktualisierungstoken: Obwohl dies nicht durch die Spezifikation vorgeschrieben ist, haben Zugriffstoken idealerweise eine Ablaufzeit, die zwischen einigen Minuten und mehreren Stunden liegen kann. Sobald ein Zugriffstoken abgelaufen ist, kann der Client den Autorisierungsserver auffordern, ein neues Zugriffstoken mithilfe des vom Autorisierungsserver ausgegebenen Aktualisierungstokens auszustellen.
Was stimmt nicht mit OAuth 1.0?
Der Hauptnachteil von OAuth 1.0 war die inhärente Komplexität, die zur Implementierung der Spezifikation erforderlich ist.
Nichts wirklich! Twitter funktioniert mit OAuth 1.0 immer noch einwandfrei und unterstützt gerade einen kleinen Teil der 2.0-Spezifikation. OAuth 1.0 war eine gut durchdachte Spezifikation und ermöglichte den sicheren Austausch geheimer Informationen ohne den durch SSL verursachten Overhead. Der Grund, warum wir eine Überarbeitung benötigten, lag hauptsächlich in der Komplexität bei der Implementierung der Spezifikation. Im Folgenden sind einige Bereiche aufgeführt, in denen OAuth 1.0 nicht beeindrucken konnte:
- Signieren jeder Anforderung: Es hat sich als großer Rückschlag für Entwickler erwiesen, wenn der Client bei jeder API-Anforderung Signaturen generiert und diese bei jedem Empfang auf dem Server überprüft, da sie die Parameter analysieren, codieren und sortieren mussten, bevor sie eine Anforderung stellten. OAuth 2.0 beseitigte diese Komplexität, indem die Token einfach über SSL gesendet wurden, wodurch das gleiche Problem auf Netzwerkebene gelöst wurde. Mit OAuth 2.0 sind keine Signaturen erforderlich.
- Adressierung nativer Anwendungen: Mit der Entwicklung nativer Anwendungen für mobile Geräte schien der webbasierte Ablauf von OAuth 1.0 ineffizient zu sein, was die Verwendung von Benutzeragenten wie einem Webbrowser erforderlich machte. OAuth 2.0 bietet mehr Flows, die speziell für native Anwendungen geeignet sind.
- Klare Rollentrennung: OAuth 2.0 bietet die dringend benötigte Rollentrennung für den Autorisierungsserver, der den Client authentifiziert und autorisiert, und für den Ressourcenserver, der API-Aufrufe für den Zugriff auf eingeschränkte Ressourcen verarbeitet.
OAuth 2.0 in Depth
Vor dem Initiieren des Protokolls muss sich der Client beim Autorisierungsserver registrieren, indem er seinen Clienttyp, seine Umleitungs-URL (zu der der Autorisierungsserver umleiten soll, nachdem der Ressourcenbesitzer den Zugriff gewährt oder ablehnt) und alle anderen vom Server benötigten Informationen angibt und erhält wiederum eine Client-ID (client_id) und ein Client-Geheimnis (client_secret). Dieser Vorgang wird als Client-Registrierung bezeichnet. Nach der Registrierung kann der Client einen der folgenden Flows verwenden, um mit dem Server zu interagieren.
Verschiedene OAuth-Flows
OAuth 2.0 bringt fünf neue Flows in die Tabelle und bietet Entwicklern die Flexibilität, einen von ihnen abhängig vom Typ des beteiligten Clients zu implementieren:
- User-Agent-Flow: Geeignet für Clients, die normalerweise in User-Agents implementiert sind (z. B. Clients, die in einem Webbrowser ausgeführt werden) und eine Skriptsprache wie JavaScript verwenden. Wird hauptsächlich von nativen Anwendungen für Mobilgeräte oder Desktops verwendet, wobei der eingebettete oder externe Browser als Benutzeragent für die Autorisierung verwendet wird und die implizite Berechtigung zum Gewähren verwendet wird.
- Webserver-Flow: Hierbei wird die Berechtigung für den Autorisierungscode verwendet. Es handelt sich um einen umleitungsbasierten Flow, der die Interaktion mit dem Benutzeragenten des Endbenutzers erfordert. Daher ist es am besten für Clients geeignet, die Teil von Webserver-basierten Anwendungen sind, auf die normalerweise über einen Webbrowser zugegriffen wird.
- Benutzername und Kennwort-Flow: Wird nur verwendet, wenn zwischen dem Client und dem Ressourcenbesitzer ein hohes Vertrauen besteht und wenn andere Datenflüsse nicht realisierbar sind, da die Anmeldeinformationen des Ressourcenbesitzers übertragen werden. Beispiele für Clients können ein Gerätebetriebssystem oder eine hochprivilegierte Anwendung sein. Das kann auch verwendet werden, um vorhandene Clients mithilfe von HTTP Basic- oder Digest-Authentifizierungsschemata nach OAuth zu migrieren, indem die gespeicherten Anmeldeinformationen in ein Access-Token konvertiert werden.
- Assertion Flow: Ihr Client kann dem Autorisierungsserver eine Assertion wie SAML Assertion als Gegenleistung für ein Zugriffstoken vorlegen.
- Clientanmeldeinformationen-Flow: OAuth wird hauptsächlich für den delegierten Zugriff verwendet. In einigen Fällen besitzt der Client jedoch die Ressource oder hat den delegierten Zugriff bereits außerhalb eines typischen OAuth-Flusses erhalten. Hier tauschen Sie einfach Client-Anmeldeinformationen gegen ein Access-Token aus.
Die ausführliche Erörterung jedes Flow würde nicht in den Geltungsbereich dieses Artikels fallen, und ich würde eher empfehlen, die Spezifikation zu lesen, um detaillierte Informationen zum Flow zu erhalten. Um ein Gefühl dafür zu bekommen, was los ist, wollen wir uns näher mit einem der am häufigsten verwendeten und unterstützten Flows befassen: dem Webserver-Flow.
Der Webserver-Flow
Da es sich um einen umleitungsbasierten Ablauf handelt, muss der Client in der Lage sein, mit dem Benutzeragenten des Ressourcenbesitzers (in den meisten Fällen ein Webbrowser) zu interagieren, und ist daher normalerweise für eine Webanwendung geeignet. Das folgende Diagramm zeigt aus der Vogelperspektive, wie der Endbenutzer (oder der Ressourcenbesitzer) die Clientanwendung (in diesem Fall eine Webserver-basierte Anwendung) verwendet, um sich beim Autorisierungsserver zu authentifizieren und zu autorisieren, um auf die geschützten Ressourcen zuzugreifen vom Ressourcenserver.



Authentifizieren und autorisieren Sie den Client
Der Client initiiert im Auftrag des Ressourcenbesitzers den Datenfluss, indem er mit einem Parameter response_type als code, einer Client-ID, die bei der Client-Registrierung abgerufen wird, einer Umleitungs-URL, einem angeforderten Bereich (optional) und einem lokalen zum Autorisierungsendpunkt umleitet Zustand (falls vorhanden). Um ein Gefühl dafür zu bekommen, wie es wirklich funktioniert, sehen Sie hier einen Screenshot, wie eine typische Anfrage/Antwort aussehen würde:



Dadurch wird dem Ressourcenbesitzer normalerweise eine Weboberfläche angezeigt, über die der Besitzer authentifizieren und prüfen kann, welche Berechtigungen die Client-App im Namen des Besitzers verwenden kann.



Unter der Annahme, dass der Ressourcenbesitzer dem Client Zugriff gewährt, leitet der Autorisierungsserver den Benutzeragenten unter Verwendung der zuvor angegebenen Umleitungs-URL zusammen mit dem Autorisierungscode, wie in der folgenden Antwort gezeigt, zurück zum Client.



Exchange-Autorisierungscode für Token
Der Client sendet dann an einen anderen Autorisierungsendpunkt und sendet den im vorherigen Schritt empfangenen Autorisierungscode zusammen mit der Umleitungs-URL, seiner Client-ID und seinem Geheimnis, die während der Client-Registrierung erhalten wurden, und ein Parameter grant_type muss als authorization_code festgelegt werden.



Der Server überprüft dann den Autorisierungscode und überprüft, ob die Umleitungs-URL mit der im vorherigen Schritt übereinstimmt. Bei Erfolg antwortet der Server mit einem Access-Token und optional einem Aktualisierungstoken.



Fordern Sie eingeschränkte Ressourcen mithilfe von Access-Token an
Der Client kann jetzt die von der Implementierung bereitgestellten APIs verwenden und den Ressourcenserver nach einer eingeschränkten Ressource abfragen, indem er das Zugriffstoken im Autorisierungsheader der Anforderung weiterleitet. Eine Beispiel-CURL-Anfrage an die Blogger-API von Google, um ein Blog mit seiner Kennung abzurufen, sieht folgendermaßen aus:
1 |
$ curl https://www.googleapis.com/blogger/v3/blogs/5223788876950011016 -H 'Authorization: OAuth ya29.AHES6ZRTj1GNxAby81Es-p_YPWWNBAFRvBYVsYj2HZJfJHU' |
Beachten Sie, dass wir das Access-Token als Autorisierungsheader in die Anforderung eingefügt und das Token auch durch einfaches Einfügen in einfache Anführungszeichen maskiert haben, da das Token möglicherweise Sonderzeichen enthält. Beachten Sie, dass das Entkommen des Access-Tokens nur bei Verwendung von Curl erforderlich ist. Daraus ergibt sich die folgende Anfrage:



Der Ressourcenserver überprüft dann die übergebenen Anmeldeinformationen (Access-Token) und antwortet bei Erfolg mit den angeforderten Informationen.



Diese Beispiele wurden mit freundlicher Genehmigung von OAuth2.0 Playground erstellt und sind typisch für die Implementierung der Spezifikation durch Google. Es können Unterschiede auftreten, wenn Sie den gleichen Ablauf mit anderen Anbietern (wie Facebook oder Salesforce) versuchen. Hier treten Interoperabilitätsprobleme auf, auf die wir etwas später eingehen.
Access-Token aktualisieren
Obwohl nicht durch die Spezifikation vorgeschrieben, sind die Zugriffstoken in der Regel nur von kurzer Dauer und haben eine Ablaufzeit. Wenn ein Zugriffstoken abgelaufen ist, sendet der Client das Aktualisierungstoken zusammen mit seiner Client-ID und seinem Geheimnis sowie einem Parameter grant_type als refresh_token an den Autorisierungsserver.



Der Autorisierungsserver antwortet dann mit dem neuen Wert für das Access-Token.



Es gibt zwar einen Befehl zum Widerruf des Aktualen Aktualisierungstokens, aber auch lebt das Aktualisierungsstoken für immer und muss Rechte und wie ein geheimer Wert erhalten werden.
Was stimmt nicht mit OAuth 2.0?
Das gute Zeug
In Anbetracht der Adoptionsrate ist OAuth 2.0 definitiv eine Verbesserung gegenüber seinem arkanen Vorgänger. Fälle, in denen die Entwicklergemeinschaft beim Implementieren der Signaturen von 1.0 ins Stocken gerät, sind nicht unbekannt. OAuth 2.0 bietet auch mehrere neue Grant-Typen, mit denen viele Anwendungsfälle wie native Anwendungen unterstützt werden können. Das Alleinstellungsmerkmal dieser Spezifikation ist jedoch die Einfachheit gegenüber der vorherigen Version.
Die schlechten Teile
Die Spezifikation enthält einige lose Enden, da einige erforderliche Komponenten nicht richtig definiert werden oder die Implementierung den Implementierungen überlassen bleibt, z. B.:
Lose Enden in der OAuth 2.0-Spezifikation führen wahrscheinlich zu einer Vielzahl nicht interoperabler Implementierungen.
- Interoperabilität: Das Hinzufügen zu vieler Erweiterungspunkte in der Spezifikation führte zu Implementierungen, die nicht miteinander kompatibel sind. Dies bedeutet, dass Sie nicht hoffen können, einen generischen Code zu schreiben, der Endpoint Discovery verwendet, um Informationen zu den von den verschiedenen Implementierungen bereitgestellten Endpunkten zu erhalten und interagieren Sie mit ihnen, stattdessen müssten Sie separate Codeteile für Facebook, Google, Salesforce usw. schreiben. Sogar die Spezifikation gibt diesen Fehler als Haftungsausschluss zu.
- Kurzlebige Token: Die Spezifikation schreibt nicht die Lebensdauer und den Umfang der ausgegebenen Token vor. Die Implementierung ist kostenlos, damit ein Token für immer lebt. Obwohl die meisten Implementierungen kurzlebige Access-Token und ein Aktualisierungstoken bereitstellen, mit denen ein neues Access-Token abgerufen werden kann.
- Sicherheit: Die Spezifikation "empfiehlt" lediglich die Verwendung von SSL/TLS, während die Token im Klartext über das Kabel gesendet werden. Obwohl bei jeder größeren Implementierung sichere Autorisierungsendpunkte erforderlich sind, muss der Client über eine sichere Umleitungs-URL verfügen. Andernfalls ist es für einen Angreifer viel zu einfach, die Kommunikation zu belauschen und die Token zu entschlüsseln.
Der hässliche Spat
Die IETF benötigte ungefähr 31 Entwurfsversionen und den Rücktritt des Hauptautors/Entwicklers Eran Hammer aus dem Komitee, um die Spezifikation endgültig zu veröffentlichen. Eran löste eine Kontroverse aus, indem er die Spezifikation "ein schlechtes Protokoll und einen Todesfall durch tausend Schnitte" nannte. Ihm zufolge war die Verwendung von Inhaber-Token (Senden von Token über SSL ohne Signieren oder sonstige Überprüfung) über den Benutzer von Signaturen (oder MAC-Tokens), die in OAuth 1.0 zum Signieren der Anforderung verwendet wurden, ein schlechter Schachzug und ein Ergebnis der Aufteilung der Interessen zwischen dem Web und Unternehmensgemeinschaften.
Abschließende Bemerkungen
Die Spezifikation lässt sicherlich viele Erweiterungspunkte offen, was zu Implementierungen führt, die zusätzlich zu den bereits definierten Parametern ihre eigenen Parameter einführen, und stellt sicher, dass Implementierungen von verschiedenen Anbietern nicht miteinander interagieren können. But going with the popularity and adoption rate of this framework, with every big player in town (Google, Twitter, Facebook, Salesforce, Foursquare, Github etc.) implementing and tweaking it the way it suits them, OAuth is far from being a failure. In fact, any web application that plans to expose their APIs to other web applications must support some form of authentication and authorization and OAuth fits the bill here.



