So behandeln Sie die Client-Anmeldeinformationen vertraulich, während Sie den Grant-Typ für die Berechtigungsnachweise für Ressourceninhaber von OAuth2 verwenden

75

Wir bauen einen Rest-Service auf und möchten OAauth 2 für die Autorisierung verwenden. Der aktuelle Entwurf (v2-16 vom 19. Mai) beschreibt vier Zuschussarten . Sie sind Mechanismen oder Abläufe zum Erhalten der Autorisierung (ein Zugriffstoken).

  1. Autorisierungscode
  2. Implizite Gewährung
  3. Anmeldeinformationen des Ressourcenbesitzers
  4. Client-Anmeldeinformationen

Es scheint, dass wir alle vier unterstützen müssen, da sie unterschiedlichen Zwecken dienen. Die ersten beiden (und möglicherweise die letzte) können von Apps von Drittanbietern verwendet werden, die Zugriff auf die API benötigen. Der Autorisierungscode ist die Standardmethode zum Autorisieren einer Webanwendung, die das Glück hat, sich auf einem sicheren Server zu befinden, während der implizite Grant-Flow die Wahl für eine Client-Anwendung ist, die ihre Anmeldeinformationen nicht ganz vertraulich behandeln kann (z. B. mobil / Desktop) Anwendung, JavaScript-Client usw.).
Wir möchten den dritten Mechanismus selbst verwenden, um eine bessere Benutzererfahrung auf Mobilgeräten zu erzielen. Anstatt den Benutzer zu einem Anmeldedialog in einem Webbrowser usw. zu führen, gibt der Benutzer einfach seinen Benutzernamen und sein Kennwort direkt in die Anwendung ein und Login. Wir möchten auch den Grant-Typ "Client-Anmeldeinformationen" verwenden, um ein Zugriffstoken zu erhalten, mit dem öffentliche Daten angezeigt werden können, die keinem Benutzer zugeordnet sind. In diesem Fall handelt es sich nicht so sehr um eine Autorisierung, sondern um einen API-Schlüssel, mit dem wir nur auf Anwendungen zugreifen, die sich bei uns registriert haben. Auf diese Weise können wir den Zugriff bei Bedarf widerrufen.

Meine Fragen sind also:

  1. Denken Sie, ich habe den Zweck der verschiedenen Zuschussarten richtig verstanden?
  2. Wie können Sie Ihre Kundenanmeldeinformationen vertraulich behandeln? Sowohl im dritten als auch im vierten Fall müssen wir die Client-ID und das Client-Geheimnis irgendwo auf dem Client haben, was nicht nach einer guten Idee klingt.
  3. Selbst wenn Sie den impliziten Grant-Typ verwenden und Ihr Client-Geheimnis nicht preisgeben, was hindert eine andere Anwendung daran, sich als App mit demselben Autorisierungsmechanismus und derselben Client-ID auszugeben?

Zusammenfassend möchten wir in der Lage sein, die Clientanmeldeinformationen und Ressourcenanmeldeinformationen zu verwenden, die aus einer Clientanwendung stammen. Für beide Flows müssen Sie das Client-Geheimnis irgendwie speichern, aber der Client ist eine mobile oder JavaScript-Anwendung, sodass diese leicht gestohlen werden können.

Georgi Stoyanov
quelle

Antworten:

55

Ich stehe vor ähnlichen Problemen und bin auch für OAuth relativ neu. Ich habe "Resource Owner Password Credentials" in unsere API implementiert, damit unsere offizielle mobile App verwendet werden kann. Die Web-Flows scheinen auf einer mobilen Plattform so schrecklich zu sein, und sobald der Benutzer eine App installiert und vertraut Da es sich um unsere offizielle App handelt, sollten sie sich wohl fühlen, wenn sie Benutzername / Passwort direkt in die App eingeben.

Das Problem ist, wie Sie hervorheben, dass mein API-Server die client_id der App nicht sicher überprüfen kann. Wenn ich ein client_secret in den App-Code / das App-Paket einbinde, ist es jedem zugänglich, der die App installiert. Wenn Sie also ein client_secret benötigen, wird der Prozess nicht sicherer. Grundsätzlich kann sich jede andere App durch Kopieren der client_id als meine App ausgeben.

Nur um die Antworten auf jeden Ihrer Punkte zu richten:

  1. Ich lese immer wieder verschiedene Entwürfe der Spezifikation, um festzustellen, ob sich etwas geändert hat, und konzentriere mich hauptsächlich auf den Abschnitt Kennwortanmeldeinformationen für Ressourcenbesitzer, aber ich denke, Sie haben diesbezüglich Recht. Kundenanmeldeinformationen (4) Ich denke, sie können auch von einem internen Dienst oder einem Drittanbieter verwendet werden, der möglicherweise Zugriff auf mehr als nur "öffentliche" Informationen benötigt, z. B. über Analysen oder Informationen, die Informationen für alle Benutzer benötigen.

  2. Ich glaube nicht, dass Sie dem Kunden etwas vertraulich behandeln können.

  3. Nichts hindert andere daran, Ihre Kunden-ID zu verwenden. Das ist auch mein Problem. Sobald Ihr Code den Server verlässt und entweder als App installiert ist oder als Javascript in einem Browser ausgeführt wird, können Sie nicht davon ausgehen, dass etwas geheim ist.

Für unsere Website hatten wir ein ähnliches Problem wie für den Client-Anmeldeinformationsfluss. Am Ende habe ich die Authentifizierung auf die Serverseite verschoben. Der Benutzer kann sich mit unserer Webanwendung authentifizieren, das OAuth-Token für unsere API wird jedoch auf der Serverseite gespeichert und der Websitzung des Benutzers zugeordnet. Alle API-Anforderungen, die der Javascript-Code stellt, sind tatsächlich AJAX-Aufrufe an den Webserver. Der Browser wird also nicht direkt mit der API authentifiziert, sondern verfügt über eine authentifizierte Websitzung.

Ihr Anwendungsfall für Client-Anmeldeinformationen scheint insofern anders zu sein, als Sie über Apps von Drittanbietern sprechen und öffentliche Daten nur über diese Methode bereitstellen. Ich denke, Ihre Bedenken sind berechtigt (jeder kann den API-Schlüssel eines anderen stehlen und verwenden), aber wenn Sie nur eine kostenlose Registrierung benötigen, um einen API-Schlüssel zu erhalten, verstehe ich nicht, warum jemand wirklich einen stehlen möchte.

Sie können die Verwendung jedes API-Schlüssels überwachen / analysieren, um Missbrauch zu erkennen. Zu diesem Zeitpunkt können Sie einen API-Schlüssel ungültig machen und dem legitimen Benutzer einen neuen geben. Dies ist vielleicht die beste Option, aber in keiner Weise sicher.

Sie können hierfür auch ein Refresh Token-ähnliches Schema verwenden, wenn Sie es etwas enger sperren möchten, obwohl ich nicht weiß, wie viel Sie wirklich gewinnen würden. Wenn Sie die mit Javascript belichteten API-Token einmal am Tag abgelaufen sind und der Drittanbieter eine serverseitige Aktualisierung mit einem (geheimen) Aktualisierungstoken durchführen muss, sind gestohlene API-Token niemals länger als einen Tag gültig. Könnte potenzielle Token-Diebe dazu ermutigen, sich stattdessen nur zu registrieren. Aber eine Art Schmerz für alle anderen, also nicht sicher, ob sich das lohnt.

Schwere
quelle
2
Ich habe ein bisschen mehr recherchiert und ich denke, Sie haben Recht - es gibt keine Möglichkeit, etwas über den Kunden geheim zu halten. Wie Sie vorschlagen, besteht unsere beste Option zum Schutz der API vor Missbrauch darin, eine Art Nutzungsüberwachung zu implementieren. Danke für deine Antwort!
Georgi Stoyanov
Lassen Sie mich wissen, wenn Sie in Zukunft bessere Lösungen finden!
Schwere
3
Ist die folgende Behauptung nur zum Verständnis richtig? * Es gibt nicht mehr Sicherheit, wenn Sie eine authentifizierte Websitzung (über ein Cookie oder so) verwenden und die Authentifizierung auf dem Server "auf die alte Art" durchführen, als wenn Sie den Grant-Typ "OAuth2 Resource Owner Password Credentials" verwenden, da dies auch eine klassische Websitzung / ein klassisches Cookie ist könnte an andere Schauspieler weitergegeben werden / könnte gestohlen werden.
Spaudanjo
1
Hat jemand von euch jemals eine Lösung für diese Probleme gefunden? Sobald ich den Flow "Resource Owner Credentials" (bester mobiler UX) öffne, kann jede Anwendung den Flow verwenden, und mein Authentifizierungsserver kann den Unterschied zwischen einer Erstanbieter- und einer Drittanbieter-App nicht erkennen .
Jarrod
4
Ich frage mich, wie Facebook, Twitter und andere kleinere, aber sehr große Unternehmen sozialer Netzwerke mit diesem Problem in ihren mobilen Anwendungen umgehen ...
Stefano Mondino