it-swarm.com.de

Authentifizierung für REST Internetdienste

Ich fange an, einen REST - Webdienst zu entwerfen, und bin unklar, wie die Authentifizierung am besten funktioniert. Der Dienst ermöglicht es einzelnen Benutzern, auf ihre eigenen Daten zuzugreifen und diese zu verwalten. Daher ist eine Art Benutzerauthentifizierung erforderlich. Ich habe mir diese Optionen angesehen:

  • OAuth

Bei OAuth geht es eher um Autorisierung als um Authentifizierung. Ich habe vor, die Autorisierung innerhalb der Dienste nativ zu behandeln, deshalb suche ich keine Lösung dafür. Aber ist OAuth auch für die Authentifizierung geeignet?

  • OpenID

OpenID bietet sicherlich eine Lösung für die Authentifizierung. Dies ist jedoch eher darauf ausgerichtet, dass Benutzer die Anmeldeinformationen von Drittanbietern (Google, Yahoo usw.) verwenden können. Auch wenn ich dies unterstützen möchte, ist dies kein Hauptanliegen für mich, und das werde ich auch Erlaube Benutzern definitiv, sich mit nativen Anmeldeinformationen (E-Mail/Passwort) anzumelden.

  • HTTP-Basisauthentifizierung

Dies ist einfach zu implementieren, aber meines Wissens ist dies möglicherweise keine sehr sichere Methode. Es scheint auch, dass für jeden Zugriff ein Austausch von Anmeldeinformationen erforderlich ist, aber ich würde es vorziehen, wenn sich der Benutzer einmalig authentifiziert und dann über ein Sitzungstoken den Zugriff fortsetzt.

  • Benutzerdefinierte Authentifizierung

Führen Sie im Allgemeinen einen eigenen Anmelde-/Tokengenerierungsdienst aus und benötigen Sie ein gültiges Token für den Zugriff auf alle anderen Ressourcen (natürlich würde alles über SSL sein).


Neben der Erstellung der Webservices werde ich auch eine Client- (Web-) Anwendung erstellen, die diese Dienste für einen Benutzer verwendet. Ich möchte jedoch nicht, dass die Anwendung Benutzerinformationen/Anmeldeinformationen/etc speichern muss. Also so etwas:

Benutzer (authentifiziert sich mit E-Mail/Passwort oder Anmeldeinformationen von Drittanbietern) -> Webanwendung (authentifiziert mit Anwendungs-ID) -> Webservices

Und wieder möchte ich auch anderen Kunden erlauben, Clients zu erstellen, sodass die mittlere Schicht eine beliebige Drittanbieteranwendung sein kann:

Benutzer (authentifiziert sich mit E-Mail/Passwort oder Anmeldeinformationen von Drittanbietern) -> Drittanbieteranwendung (authentifiziert mit Anwendungs-ID) -> Webservices

Meine höchsten Anforderungen sind:

  • Sicher (offensichtlich)
  • Native Nachweise
  • Unterstützung für Anmeldeinformationen von Drittanbietern (Google, Yahoo, LinkedIn usw.)
  • Unterstützung mehrerer Kunden (Web-App, mobile App, Apps von Drittanbietern usw.)
  • Client-Anmeldeinformationen (nur eine App-ID?)
  • Anmeldesitzungen, die ablaufen
  • Eine Autorisierung ist NICHT erforderlich 

Also, meine Frage ist, basierend auf dem oben genannten (bitte lassen Sie mich wissen, wenn dies zu vage ist), gibt es einen "besten" Ansatz? Ist OAuth oder OpenID angemessen oder mache ich das zu kompliziert und sollte stattdessen nur meine eigene Authentifizierung rollen?

BEARBEITEN:

Ich denke, ich muss Folgendes implementieren: 

1) Native Anmeldeinformationen/Tokens (HTTP-Basisauthentifizierung über SSL?) 

2) Eine OpenID "Relying Party", um meinem API die Verwendung von OpenIDs zu ermöglichen, die anderswo gehostet werden (d. H. "Unterstützung für Anmeldeinformationen von Drittanbietern").

3) Ein OAuth-"Consumer", um meinem API den Zugriff auf Dienste von Drittanbietern zu ermöglichen (z. B. Zugriff auf das LinkedIn-Profil eines Benutzers). 

4) Ein OpenID "Provider", mit dem Benutzer die nativen IDs des API an anderer Stelle verwenden können (optional). 

5) Ein OAuth-Anbieter, der Apps von Drittanbietern den Zugriff auf meine API im Namen der Benutzer ermöglicht (optional). 

Scheint das richtig oder mache ich das komplizierter, als es sein muss?

42
user2943799

Sie könnten JWT (JSON Web Token) in Betracht ziehen, siehe JWT draft rfc . Dies würde sicherlich Ihre Sicherheits- und Ablaufanforderungen erfüllen. Da es sich jedoch um einen Normentwurf handelt, ist es derzeit unwahrscheinlich, dass er allgemein verbreitet wird. Dies könnte sich bald ändern, da JWT Teil von OAuth 2.0 ist. JWT ist in den meisten Sprachen einfach zu implementieren und es gibt bereits viele Bibliotheken. Zur einfachen Erklärung besteht ein JWT-Token aus 3 Teilen, dem Header, dem Body und der Signatur. Der Header und der Rumpf sind Json-Objekte, die basee64url-codiert sind (Alphabete unterscheiden sich um 2 letzte Zeichen von base64). Anschließend werden sie mit HMAC256 (oder einem anderen im Header angegebenen Algorithmus) signiert. Der RFC erläutert, wie diese Signatur genau generiert wird. Möglicherweise möchten Sie diesen Online-Token-Generator überprüfen.

JWT sind http-Header und Abfrageparameter.

12
nullptr

Eine gute Option, die Sie in Betracht ziehen sollten, ist die Shared-Key-Authentifizierung. Dies ist die Art der Authentifizierung, die der Amazon-Webdienst und der Windows Azure-Speicherdienst verwenden. Wir haben die Shared-Key-Authentifizierung in dem von uns entwickelten REST Dienst verwendet. Sie können eine schnelle Suche in Google nach "Shared Key-Authentifizierung" durchführen. Sie erhalten viele Details. 

Ich habe einen Blogbeitrag hier darüber geschrieben.

High-Level-Schritte sind:

  1. Der Client kombiniert einen Satz eindeutiger Daten (Elemente), die vom REST Dienst definiert werden.
  2. Signieren Sie diese kombinierten Daten mit einem Schlüssel, der nur dem Client und dem REST Dienst bekannt ist
  3. Senden Sie diese Signatur als Wert für den HTTP-Header an REST Dienst
  4. Der REST-Dienst berechnet die Signatur genauso wie der Client
  5. Vergleichen Sie die vom Client gesendete Signatur mit der berechneten, wenn dieselbe davon ausgeht, dass sie eine gültige Anforderung ist
11

Mein Vorschlag ist, die erste Anforderung zu authentifizieren und dann ein Sitzungstoken einzurichten.

Die Front-End-Anwendung würde das Token speichern und mit jeder nachfolgenden Anforderung bereitstellen.

Das Token hätte eine Ablaufzeit. Das Token läuft aus, wenn es für einen bestimmten Zeitraum nicht verwendet wird.

Das Token kann der ursprünglichen IP-Adresse für zusätzliche Sicherheit zugeordnet werden.

Das Token kann als Cookie oder als Abfrageparameter in der URL übertragen werden.

Wenn die Mühe der SSL-Clientauthentifizierung akzeptabel ist, können Sie die gegenseitige SSL-Authentifizierung verwenden. Jeder Client muss mit einem Zertifikat ausgestattet werden, dem der Server vertraut. Es kann dasselbe Zertifikat sein oder verschiedene Zertifikate, wenn Sie Clients unterschiedlich behandeln müssen.

7
ArunasR

Aufgrund Ihrer Anforderungen denke ich, dass OAuth 2.0 tatsächlich eine interessante Option sein könnte. OAuth ist zwar ein Berechtigungsprotokoll, aber es Authenticates den Client mit einer clientId und einer clientSecret. Sie können Client Credential Flow verwenden und festlegen, dass Refresh Token nicht enthalten ist. Auf diese Weise verfügt der Benutzer über einen Access Token, der nach einer bestimmten Zeit abläuft. Und da OAuth ein weit verbreitetes Protokoll ist, gibt es bereits viele Client- und Serverseitenbibliotheken, die Sie und Ihre Clients verwenden können.

Wenn Sie denken, dass OAuth für Ihre Anwendung zu schwer oder zu kompliziert ist, würde ich wahrscheinlich mit Basic Authentication über HTTPS bleiben. Wie ich auch in einer anderen Antwort auf eine ähnliche Frage festgestellt habe, würde ich niemals meinen eigenen Authentifizierungsmechanismus erfinden.

Für weitere Informationen können Sie sich auch die andere Antwort ansehen, die ich zuvor auf eine ähnliche Frage gegeben habe: https://stackoverflow.com/a/15003777/849741

2
Jos Vinke

Sie können HTTP Basic Auth verwenden, bei dem das übermittelte Kennwort nicht tatsächlich ein Kennwort ist, sondern ein Token, das der Client für eine andere Ressourcenanforderung erworben hat, wobei er/sie sein Kennwort einmalig und einmalig angeben musste ( vielleicht sogar über einen anderen Kanal). Dies schützt Man-in-the-Middle-Angriffe nicht (da es keine Nachrichtensignierung gibt), aber die Idee ist, dass Sie immer verlangen können, dass der Client ein dynamisches Token generiert (z. B. über einen eigenen Auth-Dienst) und dann Lassen Sie es das Token als Kennwortersatz senden, sodass das eigentliche Kennwort nicht ständig über die Leitung übertragen wird .. Ja, dies erscheint wie eine der "benutzerdefinierten Auth-Lösungen", aber es ist eigentlich nicht so, weil Sie was festlegen können Sie müssen für das Token-Kennwort Regeln festlegen, z. B. die Verwendung eines Signatur-Tokens als Kennwort, das sitzungsgebunden oder für jede Anforderung neu berechnet wird (ohne dass dabei Geheimnisse bekannt werden), damit der Server die Nachricht überprüfen kann - was immer Ihre Anforderungen sind. Die Idee ist, das Validierungstoken als "Kennwort" der HTTP Basic Auth-Anforderung zu senden und sich nicht auf kompliziertere Protokolle zu verlassen, ohne diese (nach Ihrer Wahl) auszuschließen.

1
Kai

Ich habe einen Basisdienst implementiert und als Open Source veröffentlicht, der die Authentifizierung ermöglicht. Er kann einfach geändert werden, um bei Bedarf das 3-Tupel-Login zu ermöglichen. Es ist ungefähr 2 Jahre alt und wurde in Java über Spring geschrieben, daher möchten Sie vielleicht die Technologie überdenken, aber es funktioniert und Sie können die grundlegende Vorstellung davon bekommen, wie es gemacht wird. Finden Sie es hier bei Google oder folgen Sie meinen Blogbeiträgen darüber. Beachten Sie, dass die App nicht mehr auf Cloudbees geladen wird. Wenn Sie sie jedoch in Ihrem Konto einrichten, sollte alles in Ordnung sein.

1
TheZuck

OAuth 2.0 ist der richtige Weg, wenn Sie nur eine Autorisierung benötigen. Sie können OpenID Connect verwenden, das die Authentifizierung bereitstellt und OAuth2 unterstützt .0 zur Autorisierung. Für OepnID Connect stehen viele zertifizierte Produkte zur Verfügung, wenn Sie den Service selbst einrichten müssen. Es stehen auch viele Onlinedienste zur Verfügung.

0
Amit P

Ich empfehle die Verwendung von Spring Boot für Ihre RESTful-Webdienste, da Sie dann Spring Security verwenden können, um Ihre eigene benutzerdefinierte Authentifizierung basierend auf ihren Vorlagen zu implementieren. Sie können Ihre eigene benutzerdefinierte Authentifizierung implementieren, indem Sie ihre grundlegenden Sicherheitsklassen bzw. Schnittstellen erweitern oder implementieren. Sie haben auch die Möglichkeit, den anderen Authentifizierungsmechanismus zu integrieren, den Sie in Spring Boot aufgelistet haben, falls erforderlich.

0
Ramil