it-swarm.com.de

Implementierung von JWT-Authentifizierung und Aktualisierungstoken

Ich entwickle eine REST - Anwendung mit einem eigenen Authentifizierungs- und Autorisierungsmechanismus. Ich möchte JSON-Web-Token zur Authentifizierung verwenden. Ist das Folgende eine gültige und sichere Implementierung?

  1. Eine REST - API wird entwickelt, um Benutzername und Passwort zu akzeptieren und die Authentifizierung durchzuführen. Die zu verwendende HTTP-Methode ist POST, sodass keine Zwischenspeicherung erfolgt. Es wird auch SSL zur Sicherheit zum Zeitpunkt der Übermittlung vorhanden sein
  2. Zum Zeitpunkt der Authentifizierung werden zwei JWTs erstellt - Zugriffstoken und Aktualisierungstoken. Das Aktualisierungstoken hat eine längere Gültigkeit. Beide Token werden in Cookies geschrieben, so dass sie bei jeder nachfolgenden Anfrage gesendet werden
  3. Bei jedem REST -API-Aufruf werden die Token aus dem HTTP-Header abgerufen. Wenn das Zugriffstoken nicht abgelaufen ist, überprüfen Sie die Berechtigungen des Benutzers, und gewähren Sie den entsprechenden Zugriff. Wenn das Zugriffstoken abgelaufen ist, das Aktualisierungstoken jedoch gültig ist, erstellen Sie ein neues Zugriffstoken und ein Aktualisierungstoken mit neuen Ablaufdaten (führen Sie alle erforderlichen Überprüfungen durch, um sicherzustellen, dass die Benutzerrechte für die Authentifizierung nicht widerrufen werden), und senden Sie sie durch Cookies zurück
  4. Geben Sie eine API für das Logout REST an, die das Cookie zurücksetzt, und nachfolgende API-Aufrufe werden zurückgewiesen, bis die Anmeldung abgeschlossen ist.

Mein Verständnis von Refresh-Token hier ist:

Aufgrund des Vorhandenseins eines Aktualisierungstokens können wir eine kürzere Gültigkeitsdauer für das Zugriffstoken beibehalten und regelmäßig (nach Ablauf des Zugriffstokens) prüfen, ob der Benutzer noch zum Anmelden berechtigt ist.

Bitte korrigieren Sie mich, wenn ich falsch liege.

7
Saptarshi Basu

Eine REST - API wird entwickelt, um Benutzernamen und Passwort zu akzeptieren und die Authentifizierung. Die zu verwendende HTTP-Methode ist POST, so dass dort ist kein Caching. Zum Zeitpunkt von .__ wird auch aus Sicherheitsgründen SSL zur Verfügung stehen. Transit

So machen es die meisten, also bist du hier gut.

Zum Zeitpunkt der Authentifizierung werden zwei JWTs erstellt - Zugriffstoken und aktualisieren Sie das Token. Das Aktualisierungstoken hat eine längere Gültigkeit. Beide Token werden in Cookies geschrieben, sodass sie in jedem .__ gesendet werden. nachfolgende Anfragen

Das Speichern der Tokens in Cookies ist nicht gefährlich in sich selbst, aber wenn Sie Ihr JWT-Modul auf Ihrem Server irgendwie dazu bringen, sie von dort aus zu lesen, sind Sie anfällig für CSRF-Angriffe, bei denen jede Webseite den Browser eines Benutzers dazu veranlassen kann, ein Formular + Ihr Sites-Cookie zu senden Ihr Server, sofern Sie keine CSRF-Token verwenden. Im Allgemeinen werden sie in localStorage gespeichert und jedes Mal "manuell" zu den Anforderungsheadern hinzugefügt.

Bei jedem REST -API-Aufruf werden die Token vom HTTP .__ abgerufen. Header. Wenn das Zugriffstoken nicht abgelaufen ist, überprüfen Sie die Berechtigungen von den Benutzer und gewähren den Zugang entsprechend. Wenn das Zugriffstoken abgelaufen ist Das Aktualisierungstoken ist jedoch gültig. Erstellen Sie ein neues Zugriffstoken und aktualisieren Sie Token mit neuen Ablaufdaten (führen Sie alle erforderlichen Prüfungen durch, um sicherzustellen, dass die Benutzerrechte für die Authentifizierung nicht widerrufen werden) und über .__ zurückgesendet. Kekse

Abgesehen von den Cookie-Gefahren scheint es sicher zu sein.

Stellen Sie eine Logout REST - API bereit, die den Cookie und damit .__ zurücksetzt. Nachfolgende API-Aufrufe werden zurückgewiesen, bis die Anmeldung abgeschlossen ist.

Sie müssen nicht einmal einen API-Aufruf durchführen. Sie können einfach die Cookies oder das localStorage-Objekt löschen und sicherstellen, dass Ihr Client bei fehlenden Token nicht kaputt geht.

Der Standard für das Modul express-jwt erwartet, dass sich die Token in einem eigenen Header "Authorization: Bearer [Token]" befinden, den ich dringend über Cookies empfehlen würde. Die localStorage-API ist bis zurück zu IE8 verfügbar. Sie sollten also gut sein.

Bearbeiten:

Zunächst ist es wichtig, den Unterschied zwischen XSS- und CSRF-Angriffen zu kennen, da diese häufig als identisch angesehen werden.

XSS ist, wenn Benutzer unsichere JS in Ihrer Domäne in Browsern anderer Benutzer ausführen. In diesem Fall sind weder JWT in localStorage noch Sitzungen und JWT in Cookies sicher. Mit dem httpOnly-Flag für Cookies können Sie nicht direkt auf sie zugreifen, der Browser sendet sie jedoch weiterhin mit AJAX -Anfragen an Ihren Server. Wenn dies geschieht, haben Sie im Allgemeinen kein Glück. Um dies zu verhindern, müssen Sie alle Benutzereingaben, die an den Browser gesendet wurden, durch ein Häkchen versehen.

Wenn Sie JS von Drittanbietern mit Skript-Tags oder Iframes laden, kann dies zu einer Beeinträchtigung von localStorage führen, wenn Sie nicht aufpassen, aber ich habe nicht genug daran gearbeitet, um Ihnen hier zu helfen.

CSRF gilt nur, wenn andere Domänen versuchen, normale HTML-Formulare an Ihren Server zu senden, indem der Browser automatisch Cookies sendet. Frameworks verhindern dies, indem sie eindeutige zufällige Zeichenfolgen als ausgeblendete Felder einfügen und sie bei der Übergabe erneut prüfen. JWTs in localStorage sind hiervon ausgenommen, da jede Domäne einen eigenen localStorage-Bereich erhält.

Letztendlich hängt dies alles davon ab, ob Ihr Dienst eine einzige Domäne verwendet. In diesem Fall sind httpOnly-Cookies viel sicherer und einfacher einzurichten, wenn Sie Ihren Dienst jedoch auf mehrere Domänen wie api.domain.com + app verteilen möchten .domain.com oder fügen Sie eine native App hinzu, bei der Sie Ihre JWTs in localStorage oder einem anderen nativen Speicherbereich speichern müssen.

Hoffe das hilft!

7
Hjort-e

Mein Verständnis von Refresh-Token hier ist:

Aufgrund des Vorhandenseins eines Aktualisierungstokens können wir eine kürzere Gültigkeitsdauer für das Zugriffstoken beibehalten und regelmäßig (nach Ablauf des Zugriffstokens) prüfen, ob der Benutzer noch zum Anmelden berechtigt ist.

Bitte korrigieren Sie mich, wenn ich falsch liege.

Angenommen, Sie sprechen davon, JWT als Bearer-Token in OAuth zu verwenden (und ich würde dringend raten, das OAuth 2.0-Protokoll zu befolgen), das ist richtig. 

Mit einem zusätzlichen Auth-Zeitanspruch (Zeitstempel der Authentifizierung) in Ihrer JWT können Sie sogar das zweite Token löschen und Ihren Zugriff als Aktualisierungs-Token senden (der Auth-Server könnte dann ein neues Zugriffstoken ausgeben, wenn das Token gültig ist.) & auth-Zeit innerhalb des zulässigen Bereichs) ... aber sicher ist es auch gut, dem Standard zu folgen;) 

Es gibt jedoch einige zusätzliche Aspekte (die oft schwierig werden oder sogar gegen die Grundgedanken von JWT sind), die Sie vor der Verwendung von JWTs als Aktualisierungs-Token berücksichtigen sollten, da dies im Wesentlichen bedeutet, dass Sie eine langlebige JWT einführen:

  • müssen Sie so etwas wie eine erzwungene Benutzerabmeldung/Token-Sperrung nach Betreff haben (z. B. wenn der Benutzer als betrügerisch erkannt wurde)?
  • müssen Sie etwas wie den Widerruf eines bestimmten Tokens haben (z. B. wenn ein Benutzer ein Gerät verliert)?
  • ...

Abhängig von Ihrem Anwendungsfall sollten Sie alle möglichen Implikationen berücksichtigen, die für langlebige Token gelten, da sie normalerweise erfordern, dass Sie auf der Serverseite eine Art Status angeben (z. B. um Sperrung/Sperrliste zuzulassen). Denken Sie daran, dass die Schönheit und Sicherheit des JWT-Konzepts darin liegt, dass JWTs nur von kurzer Dauer sind. 

1
jbspeakr

Ich habe diese Frage vor zwei Jahren gestellt und auch die Antwort akzeptiert. Aufgrund meiner Erfahrung und meines Studiums in den letzten zwei Jahren möchte ich dies jedoch nur beantworten, falls jemand mit derselben Frage auf diesen Thread stößt.

Der in der Frage erwähnte Ansatz ähnelt dem Berechtigungstyp "Ressourceninhaberkennwort" von OAuth 2.0. Ich denke jedoch, dass es besser ist, statt des Browsers localStorage oder sessionStorage den Typ "Authorization Code Grant" und "Cookie" zu verwenden, um die Token zu speichern. Meine Gründe, Implementierungspunkte, Sicherheitsüberlegungen und Referenzen habe ich in dieser StackOverlow-Antwort aufgeführt.

0
Saptarshi Basu