REST-API-Anmeldemuster

181

Ich erstelle eine REST-API, die den Vorschlägen von Apigee genau folgt, Substantive verwendet, keine Verben, in die URL eingebrannte API-Version, zwei API-Pfade pro Sammlung, Verwendung von GET POST PUT DELETE usw.

Ich arbeite am Anmeldesystem, bin mir aber nicht sicher, wie REST-Benutzer ordnungsgemäß angemeldet werden sollen. Ich arbeite derzeit nicht an der Sicherheit, sondern nur am Anmeldemuster oder -ablauf. (Später werden wir 2 Schritte oAuth mit einem HMAC usw. hinzufügen.)

Möglichkeiten

  • Ein Beitrag zu so etwas https://api...com/v1/login.json
  • Ein Put zu so etwas https://api...com/v1/users.json
  • Etwas, an das ich noch nicht gedacht habe ...

Was ist der richtige REST-Stil für die Anmeldung von Benutzern?

Scott Roepnack
quelle
9
Das ist das Antwortformat. .json weist den Server an, mit json zu antworten, .xml weist den Server an, mit dem XML-Format zu antworten. Eher, dass es ein optionaler Parameter hinter dem? Ist. blog.apigee.com/detail/…
Scott Roepnack
28
Nie gesehen, dass Inhalte über die URL ausgehandelt wurden, nur in Kopfzeilen. Auf der URL bedeutet dies, dass Sie die Vorteile des Caching und mehr verlieren.
Oded
10
@ScottRoepnack dann sollten Sie den AcceptHTTP-Header berücksichtigen .
Alessandro Vendruscolo
2
@Oded Wenn Sie einen AcceptHeader verwenden, haben Sie auch einen Vary: Accept, sodass das Caching nicht beeinträchtigt wird. Conneg in Erweiterung wurde bereits zuvor besprochen . Ich würde Shonzillas Antwort dort allerdings zustimmen.
cmbuckley
2
@Oded - ich verstehe nicht. Warum sollten Sie den Vorteil des Caching verlieren, wenn Sie den Inhaltstyp in der URL angeben (entweder als JSON-Suffix für den Abfragepfad oder als Abfrageparameter type = json)? Und wer ist in diesem Fall "du"? Wer ist die Person, die die Caching-Vorteile verliert? Es scheint mir, dass die Ergebnisse einer Abfrage zwischengespeichert werden können, unabhängig davon, was sich im Abfragepfad oder in den Parametern befindet.
Cheeso

Antworten:

138

Das prinzipielle Design der modernen Webarchitektur von Roy T. Fielding und Richard N. Taylor , dh die Abfolge von Arbeiten aus allen REST-Begriffen, enthält die Definition der Client-Server-Interaktion:

Alle REST-Interaktionen sind zustandslos . Das heißt, jede Anforderung enthält alle Informationen, die ein Connector benötigt, um die Anforderung zu verstehen, unabhängig von allen Anforderungen, die ihr möglicherweise vorausgegangen sind .

Diese Einschränkung erfüllt vier Funktionen: 1. und 3. sind in diesem speziellen Fall wichtig:

  • Erstens : Die Konnektoren müssen den Anwendungsstatus zwischen den Anforderungen nicht mehr beibehalten , wodurch der Verbrauch physischer Ressourcen verringert und die Skalierbarkeit verbessert wird.
  • 3. Es ermöglicht einem Vermittler, eine Anforderung isoliert anzuzeigen und zu verstehen. Dies kann erforderlich sein, wenn Dienste dynamisch neu angeordnet werden.

Und jetzt kehren wir zu Ihrem Sicherheitsfall zurück. Jede einzelne Anfrage sollte alle erforderlichen Informationen enthalten, und Autorisierung / Authentifizierung ist keine Ausnahme. Wie erreicht man das? Senden Sie bei jeder Anfrage buchstäblich alle erforderlichen Informationen über Kabel.

Eines der Beispiele, wie dies archiviert werden kann, ist der Hash-basierte Nachrichtenauthentifizierungscode oder HMAC . In der Praxis bedeutet dies, jeder Anforderung einen Hash-Code der aktuellen Nachricht hinzuzufügen. Hash-Code, berechnet durch kryptografische Hash-Funktion in Kombination mit einem geheimen kryptografischen Schlüssel . Die kryptografische Hash-Funktion ist entweder vordefiniert oder Teil der Code-on-Demand- REST-Konzeption (z. B. JavaScript). Der Server sollte dem Client einen geheimen kryptografischen Schlüssel als Ressource zur Verfügung stellen, der vom Client zur Berechnung des Hash-Codes für jede Anforderung verwendet wird.

Es gibt viele Beispiele für HMAC- Implementierungen, aber ich möchte, dass Sie die folgenden drei beachten:

Wie es in der Praxis funktioniert

Wenn der Client den geheimen Schlüssel kennt, kann er mit Ressourcen arbeiten. Andernfalls wird er vorübergehend umgeleitet (Statuscode 307 Temporäre Umleitung), um einen geheimen Schlüssel zu autorisieren und abzurufen, und dann zurück zur ursprünglichen Ressource umgeleitet. In diesem Fall müssen Sie nicht vorher wissen (dh irgendwo fest codieren), wie die URL lautet , um den Client zu autorisieren , und es ist möglich, dieses Schema mit der Zeit anzupassen.

Ich hoffe, dies hilft Ihnen, die richtige Lösung zu finden!

Akim
quelle
23
Ein MAC soll die Authentizität von Nachrichten beweisen und vor Manipulationen schützen - er hat nichts mit Benutzerauthentifizierung zu tun
yrk
1
Es wurde eines der Beispiele hinzugefügt, wie die Benutzer- / Client-Authentifizierung ohne
Akim
Hier sind zwei weitere schöne Artikel mit Beispielen für zustandslose Authentifizierung für REST-Services: blog.jdriven.com/2014/10/… technischrex.com/2015/02/20/…
Vladimir Rozhkov
41

TL; DR Die Anmeldung für jede Anforderung ist keine erforderliche Komponente, um die API-Sicherheit zu implementieren. Die Authentifizierung ist.

Es ist schwierig, Ihre Frage zum Login zu beantworten, ohne allgemein über Sicherheit zu sprechen. Bei einigen Authentifizierungsschemata gibt es keine herkömmliche Anmeldung.

REST schreibt keine Sicherheitsregeln vor, aber die in der Praxis am häufigsten verwendete Implementierung ist OAuth mit 3-Wege-Authentifizierung (wie Sie in Ihrer Frage erwähnt haben). Es gibt keine Anmeldung an sich, zumindest nicht bei jeder API-Anforderung. Bei der 3-Wege-Authentifizierung verwenden Sie nur Token.

  1. Der Benutzer genehmigt den API-Client und erteilt die Berechtigung, Anforderungen in Form eines langlebigen Tokens zu stellen
  2. Der API-Client erhält ein kurzlebiges Token, indem er das langlebige verwendet.
  3. Der API-Client sendet das kurzlebige Token bei jeder Anforderung.

Dieses Schema gibt dem Benutzer die Möglichkeit, den Zugriff jederzeit zu widerrufen. Praktisch alle öffentlich verfügbaren RESTful-APIs, die ich gesehen habe, verwenden OAuth, um dies zu implementieren.

Ich denke nur nicht, dass Sie Ihr Problem (und Ihre Frage) in Bezug auf die Anmeldung einrahmen sollten, sondern darüber nachdenken sollten, die API im Allgemeinen zu sichern.

Weitere Informationen zur Authentifizierung von REST-APIs im Allgemeinen finden Sie in den folgenden Ressourcen:

Slavo
quelle
Ja, OAuth! Sehr einfache Antwort, sollte die akzeptierte Antwort sein, imho.
Levite
26

Ein großer Teil der REST-Philosophie besteht darin, beim Entwurf Ihrer API so viele Standardfunktionen des HTTP-Protokolls wie möglich zu nutzen. Wenn Sie diese Philosophie auf Authentifizierung, Client und Server anwenden, werden Standard-HTTP-Authentifizierungsfunktionen in der API verwendet.

Anmeldebildschirme eignen sich hervorragend für Anwendungsfälle menschlicher Benutzer: Besuchen Sie einen Anmeldebildschirm, geben Sie Benutzer / Kennwort ein, setzen Sie ein Cookie, der Client stellt dieses Cookie in allen zukünftigen Anforderungen bereit. Von Menschen, die Webbrowser verwenden, kann nicht erwartet werden, dass sie bei jeder einzelnen HTTP-Anforderung eine Benutzer-ID und ein Kennwort angeben.

Für eine REST-API sind ein Anmeldebildschirm und Sitzungscookies jedoch nicht unbedingt erforderlich, da jede Anforderung Anmeldeinformationen enthalten kann, ohne einen menschlichen Benutzer zu beeinträchtigen. und wenn der Kunde zu irgendeinem Zeitpunkt nicht kooperiert, kann eine 401"nicht autorisierte" Antwort gegeben werden. RFC 2617 beschreibt die Authentifizierungsunterstützung in HTTP.

TLS (HTTPS) wäre ebenfalls eine Option und würde die Authentifizierung des Clients gegenüber dem Server (und umgekehrt) bei jeder Anforderung ermöglichen, indem der öffentliche Schlüssel der anderen Partei überprüft wird. Zusätzlich sichert dies den Kanal für einen Bonus. Dazu ist natürlich vor der Kommunikation ein Schlüsselpaaraustausch erforderlich. (Beachten Sie, dass es speziell darum geht, den Benutzer mit TLS zu identifizieren / zu authentifizieren. Das Sichern des Kanals mithilfe von TLS / Diffie-Hellman ist immer eine gute Idee, auch wenn Sie den Benutzer nicht anhand seines öffentlichen Schlüssels identifizieren.)

Ein Beispiel: Angenommen, ein OAuth-Token sind Ihre vollständigen Anmeldeinformationen. Sobald der Client über das OAuth-Token verfügt, kann es bei jeder Anforderung als Benutzer-ID in der Standard-HTTP-Authentifizierung angegeben werden. Der Server kann das Token bei der ersten Verwendung überprüfen und das Ergebnis der Überprüfung mit einer Lebensdauer zwischenspeichern, die bei jeder Anforderung erneuert wird. Jede Anforderung, die eine Authentifizierung erfordert, wird zurückgegeben, 401wenn sie nicht angegeben wird.

wberry
quelle
1
"Da jede Anforderung Anmeldeinformationen enthalten kann, ohne einen menschlichen Benutzer zu beeinträchtigen" 3-Wege-Authentifizierung und OAuth wurden erfunden, weil die Sache in den Anführungszeichen schlecht ist. Wenn Sie bei jeder Anforderung Anmeldeinformationen angeben, ohne dass auf dem Server ein Mechanismus zum Widerrufen vorhanden ist, ist dies bei Verwendung ohne SSL unsicher.
Slavo
1
Immer wenn es ein Benutzerkonzept gibt, muss etwas vom Client an den Server übergeben werden, um den Benutzer zu identifizieren. Ein OAuth-Token kann hier sicherlich als "Anmeldeinformationen" anstelle einer tatsächlichen Benutzer- / Kennwortkombination dienen. Das Sichern des Kanals mit TLS ist sicherlich immer eine gute Sache, aber das ist fast nebensächlich. Selbst wenn Sie ein Cookie verwenden, wird bei jeder Anforderung eine Art Token an den Server gesendet, nur mit einem Cookie-Header anstelle eines Authentifizierungs-Headers.
Wberry
Und wenn Sie TLS oder OAuth aus irgendeinem Grund nicht verwenden, ist das Senden eines Benutzers / Passworts jedes Mal wirklich schlimmer als das einmalige Senden? Wenn der Angreifer den Benutzer / das Kennwort erhalten kann, kann der Angreifer wahrscheinlich auch das Sitzungscookie erhalten.
Wberry
Der Unterschied zwischen einem Cookie und einem Authentifizierungsheader als Anmeldeinformationen besteht darin, dass Cookies immer einer bestimmten Domäne zugeordnet sind. Dies bedeutet, dass die API, wenn sie ein Cookie empfängt, weiß, woher es stammt (wurde zuvor von derselben Domain geschrieben). Mit einem Header wissen Sie nie und müssen dafür spezifische Prüfungen durchführen. Im Allgemeinen stimme ich zu, dass es sich bei beiden um Anmeldeinformationen handelt, aber ich denke, dass das Übergeben von Anmeldeinformationen keine Anmeldung ist. Login ist die aktive Aktion zum Öffnen der Tür. Bei 3-Wege-Authentifizierung ist nur die erste Genehmigung des Clients die Anmeldung.
Slavo