REST-API-Authentifizierung

181

Ich erstelle eine Anwendung, die auf einem Server gehostet wird. Ich möchte eine API für die Anwendung erstellen, um die Interaktion mit jeder Plattform (Web App, Mobile App) zu erleichtern. Was ich nicht verstehe, ist, dass wir den Benutzer bei Verwendung der REST-API authentifizieren.

Zum Beispiel, wenn sich ein Benutzer angemeldet hat und dann ein Forenthema erstellen möchte. Woher weiß ich, dass der Benutzer bereits angemeldet ist?

Noor
quelle
4
Sie sollten hier wahrscheinlich nach "REST-Authentifizierung" suchen. Es wurde in vielen anderen Fragen behandelt.
Brian Kelly
10
Kurz gesagt, lassen Sie den Client bei jeder Anforderung einen Benutzernamen und ein Kennwort über HTTP Basic Auth (über SSL!) Senden oder authentifizieren Sie sich einmal, damit der Client eine authentifizierte Sitzung hat, die nach einer gewissen Zeit der Inaktivität abläuft (oder wie auch immer Sie sie überschreiben möchten) Sitzungsbehandlung Ihres Webframeworks). Diese Sitzung kann dann in einem Cookie gespeichert werden oder ein Parameter sein, der bei jeder Anforderung übergeben wird (z. B. JSESSIONID in Java Land).
Opyate
@opyate Aus Sicherheitsgründen ist es keine gute Idee, die Sitzung mithilfe von Cookies in einem REST-API-Fall zu behandeln, da Angreifer Anforderungen ohne Zustimmung des Benutzers senden können. Es ist besser, einen Sitzungs-Hash oder ein Token in einen HTTP-Header aufzunehmen (z. B. Autorisierung).
s3v3n
1
@ s3v3n Korrigieren Sie mich, wenn ich falsch liege, aber sowohl Ihre als auch meine Vorschläge sind nur verschiedene Möglichkeiten, eine Kombination aus Header und lokalem Speicher zu verwenden, um dasselbe zu bewirken. Es ist AuthorizationHeader + zB Browser localStorage VS CookieHeader + Standard-Browser-Cookie-Speicher.
Opyate

Antworten:

72

Sie können die HTTP Basic- oder Digest-Authentifizierung verwenden. Sie können Benutzer sicher mit SSL darüber authentifizieren, dies verlangsamt jedoch die API ein wenig.

  • Grundlegende Authentifizierung - Verwendet die Base64-Codierung für Benutzername und Kennwort
  • Digest-Authentifizierung - hascht den Benutzernamen und das Kennwort, bevor sie über das Netzwerk gesendet werden.

OAuth ist das Beste, was es bekommen kann. Die Vorteile, die oAuth bietet, sind widerrufliche oder ablaufbare Token. Informationen zur Implementierung finden Sie im Folgenden: Arbeitslink aus Kommentaren: https://www.ida.liu.se/~TDP024/labs/hmacarticle.pdf

ankitjaininfo
quelle
4
Bitte lesen Sie diese Frage und die Antwort von Les Hazelwood (Autor von Apache Shiro).
justin.hughey
1
Nützlicher Link, wie Twitter seine REST-API schützt: Twitter REST API-Sicherheit
WildDev
Da dies die akzeptierte Antwort ist, ist es mir wichtig zu erwähnen, dass Sie auch die Digest-Authentifizierung verwenden können. Lesen Sie hier über Unterschiede zwischen Basic-
Rayee Roded
116

Zum Beispiel, wenn ein Benutzer angemeldet ist. Angenommen, der Benutzer möchte ein Forenthema erstellen. Woher weiß ich, dass der Benutzer bereits angemeldet ist?

Denken Sie darüber nach - es muss einen Handshake geben, der Ihrer API "Forum erstellen" mitteilt, dass diese aktuelle Anforderung von einem authentifizierten Benutzer stammt. Da REST-APIs normalerweise zustandslos sind, muss der Status irgendwo beibehalten werden . Ihr Client, der die REST-APIs verwendet, ist für die Aufrechterhaltung dieses Status verantwortlich. Normalerweise handelt es sich um ein Token, das seit der Anmeldung des Benutzers weitergegeben wird. Wenn das Token gut ist, ist Ihre Anfrage gut.

Überprüfen Sie, wie Amazon AWS Authentifizierungen durchführt. Dies ist ein perfektes Beispiel für das "Weitergeben des Geldes" von einer API an eine andere.

* Ich dachte daran, meiner vorherigen Antwort eine praktische Antwort hinzuzufügen. Probieren Sie Apache Shiro (oder eine beliebige Authentifizierungs- / Autorisierungsbibliothek) aus. Fazit: Vermeiden Sie benutzerdefinierte Codierungen. Sobald Sie Ihre Lieblingsbibliothek integriert haben (ich verwende übrigens Apache Shiro), können Sie Folgendes tun:

  1. Erstellen Sie eine Login / Logout-API wie: /api/v1/loginundapi/v1/logout
  2. Führen Sie in diesen Anmelde- und Abmelde-APIs die Authentifizierung mit Ihrem Benutzerspeicher durch
  3. Das Ergebnis ist ein Token (normalerweise JSESSIONID), das an den Client zurückgesendet wird (Web, Mobile, was auch immer).
  4. Ab diesem Zeitpunkt enthalten alle nachfolgenden Anrufe Ihres Kunden dieses Token
  5. Angenommen, Ihr nächster Aufruf erfolgt an eine aufgerufene API /api/v1/findUser
  6. Der API-Code überprüft zunächst das Token ("Ist dieser Benutzer authentifiziert?").
  7. Wenn die Antwort als NEIN zurückgegeben wird, werfen Sie einen HTTP 401-Status zurück auf den Client. Lass sie damit umgehen.
  8. Wenn die Antwort JA lautet, fahren Sie mit der Rückgabe des angeforderten Benutzers fort

Das ist alles. Hoffe das hilft.

Kingz
quelle
Was Sie also beschreiben, ist im Wesentlichen ein Sitzungscookie, oder?
LordOfThePigs
Ja, aber die Sitzung wird an 2 verschiedenen Orten "gepflegt". Eine auf dem API-Server, eine andere im Browser. Die JSON-Antwort (oder was auch immer) auf die erfolgreiche Anmeldung nach dem Browser sollte die Sitzungs-ID auf dem API-Server an den Browser zurücksenden. Diese Sitzungen werden unabhängig von ihren jeweiligen Agenten verwaltet.
Kingz
11
Ich glaube, Kingz hat versucht, die Idee zu vermitteln, dass der Mechanismus zur Aufrechterhaltung der Sitzung absichtlich vage ist. Ein Sitzungscookie ist nur eine Implementierung dieses Mechanismus.
justin.hughey
2
@Kingz, Was ist mit der Sicherheit in dieser Lösung, zum Beispiel, wenn ein Hacker den Link mit session_id schnüffelt und anfängt, Anfragen zu senden, deren Inhalt die session_id korrigiert? Wir können es lösen, indem wir ssl zur Serververbindung hinzufügen, aber was ist mit Clients?
Ahmad Samilo
1
Wie kann verhindert werden, dass eine Sitzung im Fall von Man-in-the-Middle-Attrack entführt wird?
m0z4rt
38
  1. Verwenden Sie HTTP Basic Auth , um Clients zu authentifizieren, behandeln Sie Benutzername / Kennwort jedoch nur als temporäres Sitzungstoken .

    Das Sitzungstoken ist nur ein Header, der an jede HTTP-Anforderung angehängt wird , z. B.: Authorization: Basic Ym9ic2Vzc2lvbjE6czNjcmV0

    Die obige Zeichenfolge Ym9ic2Vzc2lvbjE6czNjcmV0 ist nur die in Base64 codierte Zeichenfolge "bobsession1: s3cret" (ein Benutzername / Kennwort).

  2. Um das oben genannte temporäre Sitzungstoken zu erhalten, geben Sie eine API-Funktion (z. B. http://mycompany.com/apiv1/login:) an, die den Master-Benutzernamen und das Master-Kennwort als Eingabe verwendet, einen temporären HTTP-Basisauthentifizierungs-Benutzernamen / das temporäre Kennwort auf der Serverseite erstellt und das Token zurückgibt (z. Ym9ic2Vzc2lvbjE6czNjcmV0). Dieser Benutzername / dieses Passwort sollte vorübergehend sein und nach etwa 20 Minuten ablaufen.

  3. Stellen Sie für zusätzliche Sicherheit sicher, dass Ihr REST-Service über HTTPS bereitgestellt wird, damit Informationen nicht im Klartext übertragen werden

Wenn Sie Java verwenden, bietet die Spring Security-Bibliothek eine gute Unterstützung für die Implementierung der oben genannten Methode

Gerrytan
quelle
1
Warum sollte es nach 20 Minuten ablaufen? Was ist, wenn es sich um eine Website wie Facebook handelt, bei der die Anmeldung erfolgt, bis sich der Benutzer abmeldet?
Dejell
1
@dejel Ich war unter der Annahme, dass "Sitzung" vorübergehender Natur ist. Es ist üblich, dass es abläuft, wenn der Benutzer im Leerlauf ist
gerrytan
Wofür ist die Base64? Sie können einfach das temporäre Passwort zurückgeben. In beiden Fällen ist es wirklich wichtig, dass dieses temporäre Passwort sicher ist. Überprüfen Sie security.stackexchange.com/a/19686/72945
e18r
7

Ich denke, der beste Ansatz ist die Verwendung von OAuth2. Google es und Sie werden viele nützliche Beiträge finden, die Ihnen beim Einrichten helfen.

Dies erleichtert die Entwicklung von Clientanwendungen für Ihre API aus einer Web-App oder einer mobilen App.

Hoffe es hilft dir.

Paulo Henrique
quelle
2
Bitte lesen Sie diese Frage und die Antwort von Les Hazelwood (Autor von Apache Shiro).
justin.hughey
0

Ich habe die JWT-Authentifizierung verwendet. Funktioniert gut in meiner Anwendung.

Es gibt eine Authentifizierungsmethode, für die die Benutzeranmeldeinformationen erforderlich sind. Diese Methode überprüft die Anmeldeinformationen und gibt bei Erfolg ein Zugriffstoken zurück.

Dieses Token muss an jede andere Methode in meiner Web-API im Header der Anforderung gesendet werden.

Es ist ziemlich einfach zu implementieren und sehr einfach zu testen.

Arthur Medeiros
quelle