webentwicklung-frage-antwort-db.com.de

Best Practices für das Verwalten von Authentifizierungstoken

Ich schreibe einen REST - Client in Java mit dem HttpCLient. Die REST - API, auf die ich zugreife, benötigt für jede REST - Aktion ein Auth-Token. Dieses Token ist 24 Stunden gültig.

Die Art und Weise, wie ich dies jetzt handle, ist das Aufrufen einer "getAuth()" -Methode jedes Mal, wenn ich einen REST - Aufruf machen muss, der auf dem Auth-Server wie ein Overhead erscheint. 

Wie kann ich dieses Authentifizierungs-Token bequem speichern und seinen Lebenszyklus verwalten? Gibt es dokumentierte Best Practices?

Ich dachte an die folgende Lösung

public class MySession {
    String user;
    String pass;
    public MySession(String user, String pass) {
        this.user = user;
        this.pass = pass;
    }

    public getAuth() {
        //user user, pass to get auth token 
    }
}

und übergeben Sie dann das Sessions-Objekt an eine Klasse, die das Token benötigt. Wenn das Token abgelaufen ist, rufen Sie diese Methode einfach erneut auf

18
user_mda

Der Kürze halber nehme ich an, Sie nennen einen Endpunkt, den Sie nicht ändern können. Wie Sie implementieren sollten, hängt stark davon ab, ob das Token app- oder benutzerbasiert ist (ein Token für alle Benutzer einer gemeinsam genutzten Anwendungsinstanz oder ein Token pro Benutzer).

Wenn es sich um ein Authentifizierungs-Token für die gesamte App handelt:

  • Speichern Sie es zusammen mit einem Time-to-Live-Zeitstempel im Speicher ab (oder fangen Sie den Fehler des abgelaufenen Tokens ab, fordern Sie ein neues Token an und wiederholen Sie die ursprüngliche Anforderung). Aktualisieren Sie ihn, falls er nicht existiert/abgelaufen ist
  • Wenn Sie besorgt sind, API-Token nach einem Anwendungsneustart erneut anzufordern, speichern Sie sie auch in der Datenbank und laden Sie sie beim Start, falls vorhanden

Wenn es ein Token pro Benutzer ist:

  • Speichern Sie es in Ihrer Benutzersitzung. Es ist genau das, wofür Sitzungen verwendet werden. Wenn Sie Benutzer authing, haben sie eine Sitzung und der Overhead ist bereits vorhanden
  • Wenn Sie nicht jedes Mal ein Token erneut anfordern möchten, speichern Sie das aktuelle Token in der Datenbank und laden es bei der Anmeldung in ihre Sitzung
6
Dave L

Ich gehe davon aus, dass Sie OAuth zur Autorisierung verwenden. Ob Sie JWT oder andere Token verwenden, ist für diese Situation unerheblich.

Bei der Autorisierung erhalten Sie einen access_token mit Ablaufdatum und je nach Art der von Ihnen beantragten Art (Client-Berechtigungsnachweis, Autorisierungscode, implizit, Ressourcenbesitzer) einen refresh_token.

Der Client sollte den access_token und den Ablauf beibehalten. Das Refresh_token muss, falls es ausgegeben wird, geheim gehalten werden (achten Sie darauf, dass Sie die richtige Zuteilung für Ihren Anwendungsfall verwenden).

Bei nachfolgenden Aufrufen sollte Ihr Client bei jedem Anruf keine neuen Token anfordern, sondern den gespeicherten access_token verwenden.

Wenn die API anfängt, 401 Unauthorized zurückzugeben, ist der access_token wahrscheinlich abgelaufen. Ihr Client sollte versuchen, den access_token mit dem refresh_token zu aktualisieren, falls Sie einen haben.

Wenn Sie keinen refresh_token haben oder die Aktualisierungsanforderung ebenfalls fehlgeschlagen ist, da der refresh_token nicht mehr gültig ist, können Sie einen neuen Autorisierungsablauf durchführen.

Sie können die Ablaufzeit als Anhaltspunkt verwenden, um zu wissen, wann Sie einen neuen access_token erhalten, entweder durch Aktualisierung oder durch einen neuen vollständigen Autorisierungsfluss. Dadurch wird der 401 Unauthorized vermieden. In jedem Fall sollte Ihr Client über eine Rückfallrichtlinie verfügen, wenn diese Antwort empfangen wird, nachdem für einige Anrufe ein gültiger access_token verwendet wurde.

3
Daniel Cerecedo

Wenn Sie sich Sorgen über zu viele Zugriffe auf die Datenbank machen, gehe ich davon aus, dass es eine Menge Webaktivitäten gibt. 

Ich würde die Verwendung von Session in Ihrem Fall nicht empfehlen, sondern das Token in einem Cookie auf dem Client speichern. 

In einer Umgebung mit hohem Datenaufkommen (was ich für Ihre voraussetze) kann die Verwendung von Session viel Serverspeicher beanspruchen, und die Skalierbarkeit kann ebenfalls ein Problem sein, da Sitzungen innerhalb eines Clusters synchron gehalten werden müssen. 

Wie @ Cássio Mazzochi Molin auch erwähnt hat, können Sie einen In-Memory-Cache verwenden, um benutzerspezifische Daten und Token zu speichern. Dadurch werden die Zugriffe auf die Datenbank reduziert und Sie können die Anwendung bei Bedarf auch einfacher skalieren.

3
grizzthedj

Ich schlage vor, folgendes Szenario zu verwenden:

1) Rufen Sie zuerst auth(username, password) rest api auf, um das Auth-Token abzurufen. Wenn die angegebenen Berechtigungsnachweise in Ordnung sind, senden Sie das Auth-Cookie mit dem HTTP 200-Antwortcode an den Client zurück.

2) Dann können Sie Protected Rest Apis aufrufen. Sie müssen jedes Mal ein Authentifizierungs-Cookie mit Ihrer Anfrage senden.

3) Der Servlet-Filter (oder ähnliches) überprüft jede eingehende Anforderung und validiert das Token. Wenn das Token gültig ist, wird die Anforderung an die Rest-Methode weitergeleitet, andernfalls müssen Sie eine http 401/403-Antwort generieren.

Ich schlage vor, dass Sie keine eigene Authentifizierungsschicht schreiben. Anstelle eines vorhandenen installieren und verwenden. Ich schlage vor, dass Sie OpenAM . Es ist ein hervorragendes Open Source Access Management System. 

Ich empfehle Ihnen außerdem, die Sitzung auf der Serverseite nicht zu Authentifizierungszwecken zu öffnen. Wenn Sie 10 Clients haben, müssen 10 Sitzungen vom Server verwaltet werden. Es ist kein großes Problem. Wenn Sie jedoch 100 oder 1000 oder Millionen verschiedene Clients haben, benötigen Sie mehr Speicher zum Speichern von Sitzungen auf dem Server.

3
zappee

Sie sollten JsonWebToken (kurz JWT) für diese Art von Sachen verwenden. JWT verfügt über eine integrierte Unterstützung zum Festlegen des Ablaufdatums. Es gibt viele Bibliotheken, die diese Methode verwenden, und Sie können mehr lesen here

Es gibt derzeit 4 Java-Implementierungen, und alle können prüfen, ob das Token noch gültig ist (Exp-Check) enter image description here

2
Murf

Wenn ich das richtig verstehe, verwenden Sie dasselbe Token für alle Ihre Anforderungen (dh solange Ihre App läuft und Sie die Token aktualisieren, sollten Sie in Ordnung sein. Ich hatte buchstäblich das gleiche Problem und dies ist der Fall Wie habe ich das Problem gelöst? Ich habe eine Singleton-Klasse, die beim Start der App einmalig initialisiert wird und das Token aktualisiert, wenn es ungültig gemacht wird. Ich verwende C #, Asp.NET MVC5 und AutoFac für DI, bin aber sicher Sie können dasselbe mit Java und Spring tun.

Eigenschaft eines Singleton mit Thread Safety aktualisieren

2
Mavi Domates

Sie können einen Manager erstellen und das Authentifizierungscookie während der Anmeldung in Thread Local wie dem folgenden Code speichern. Sie können den Cookie von getAuth() erhalten, solange der Thread läuft.

public class Manager {
    private static final ThreadLocal<String> SECURITY_CONTEXT = new ThreadLocal<>();

    public static void setAuth(String auth) {
        SECURITY_CONTEXT.set(auth);
    }

    public static String getAuth() {
        return SECURITY_CONTEXT.get();
    }

    public static void clear(){
        SECURITY_CONTEXT.remove();
    }
}
2

Der De-facto-Standard implementiert keine eigene Lösung (Grundregel in der Sicherheit: Implementiere keine eigenen Sachen!), Sondern verwende die De-facto-Standardlösung, nämlich JSON Web Tokens .

Dokumentation auf der Site, aber die Grundidee ist, dass Sie nur einen Wert speichern müssen (den privaten Schlüssel des Servers), und dann können Sie jeden ursprünglich vom Server ausgestellten Anspruch überprüfen (der in Ihrem Fall eine Ablaufzeit enthält). .

2
D. Kovács

Verwenden Sie json Web Token, um Informationen zwischen zwei Clients auszutauschen. Das Token ist nur für die Dauer von 24 Stunden aktiv. Danach werden alle darauffolgenden Aufrufe im Header zurückgewiesen.

0
Remario