REST-API-Sicherheit Gespeichertes Token vs JWT vs OAuth

104

Ich versuche immer noch, die beste Sicherheitslösung für den Schutz der REST-API zu finden, da die Anzahl der mobilen Anwendungen und APIs von Tag zu Tag zunimmt.

Ich habe verschiedene Arten der Authentifizierung ausprobiert, habe aber immer noch einige Missverständnisse. Daher benötige ich den Rat eines erfahrenen Mitarbeiters.

Lassen Sie mich sagen, wie ich das alles verstehe. Wenn ich etwas falsch verstehe, lassen Sie es mich bitte wissen.

Soweit die REST-API wie auch das WEB im Allgemeinen zustandslos ist, müssen wir bei jeder Anforderung einige Authentifizierungsdaten (Cookies, Token ...) senden. Ich kenne drei weit verbreitete Mechanismen zur Benutzerauthentifizierung

  1. Token mit HTTPS. Ich habe diesen Ansatz oft verwendet, es ist gut genug mit HTTPS. Wenn der Benutzer das richtige Kennwort und die richtige Anmeldung angibt, erhält er als Antwort ein Token und verwendet es für die weiteren Anforderungen. Das Token wird vom Server generiert und gespeichert, z. B. in der separaten Tabelle oder in derselben, in der Benutzerinformationen gespeichert sind. Daher prüft der Server für jede Anforderung, ob der Benutzer über ein Token verfügt und dasselbe wie in der Datenbank. Alles ist ziemlich einfach.

  2. JWT-Token. Dieses Token ist selbsterklärend und enthält alle erforderlichen Informationen zum Token selbst. Der Benutzer kann beispielsweise das Ablaufdatum oder einen anderen Anspruch nicht ändern, da dieses Token vom Server mit einem geheimen Schlüsselwort generiert (signiert) wird. Das ist auch klar. Aber ein großes Problem, persönlich für mich, wie man Token ungültig macht.

  3. OAuth 2. Ich verstehe nicht, warum dieser Ansatz verwendet werden sollte, wenn die Kommunikation direkt zwischen Server und Client hergestellt wird. Soweit ich weiß, wird der OAuth-Server verwendet, um Token mit eingeschränktem Gültigkeitsbereich auszugeben, damit andere Anwendungen auf Benutzerinformationen zugreifen können, ohne Kennwort und Anmeldung zu speichern. Dies ist eine großartige Lösung für soziale Netzwerke. Wenn Benutzer sich auf einer Seite anmelden möchten, kann der Server Berechtigungen anfordern, um Benutzerinformationen abzurufen, beispielsweise von Twitter oder Facebook, und Registrierungsfelder mit Benutzerdaten usw. füllen.

Betrachten Sie Mobile Client für Online-Shop.

Erste Frage, sollte ich JWT dem ersten Token vorziehen? Soweit ich einen Benutzer zum Anmelden / Abmelden auf einem mobilen Client benötige, muss ich irgendwo ein Token speichern oder im Falle von JWT sollte das Token beim Abmelden ungültig werden. Zum Ungültigmachen des Tokens werden verschiedene Ansätze verwendet. Eine davon ist das Erstellen einer ungültigen Token-Liste (Blacklist). Hmm. Die Tabelle / Datei ist viel größer als wenn das Token in der Tabelle gespeichert und dem Benutzer zugeordnet und nur beim Abmelden entfernt wurde.

Was sind die Vorteile von JWT-Token?

Zweite Frage zu OAuth: Soll ich sie bei direkter Kommunikation mit meinem Server verwenden? Was ist der Zweck einer weiteren Schicht zwischen Client und Server, um nur Token auszugeben, aber die Kommunikation erfolgt nicht mit einem anderen Server, sondern mit dem Hauptserver? Soweit ich weiß, ist der OAuth-Server nur dafür verantwortlich, Apps von Drittanbietern Berechtigungen (Token) für den Zugriff auf private Benutzerinformationen zu erteilen. Meine mobile Client-Anwendung ist jedoch kein Drittanbieter.

CROSP
quelle
Danke, ich habe mich das kürzlich gefragt. Ich habe mich für die Sitzungsverwaltung (Beaker) entschieden und die Sitzungstoken nach einer Stunde gelöscht. Oauth schien nicht richtig zu passen.
JasTonAChair

Antworten:

86

Betrachten Sie den ersten Fall. Jeder Client erhält eine zufällige ID, die für die Dauer der Sitzung gültig ist - auf Wunsch auch für mehrere Tage. Anschließend speichern Sie die für diese Sitzung relevanten Informationen an einem Server. Es kann sich um eine Datei oder eine Datenbank handeln. Nehmen wir an, Sie übergeben die ID über ein Cookie, können jedoch die URL oder einen HTTP-Header verwenden.

Sitzungs-IDs / Cookies

Vorteile:

  • Einfach, den Klienten und den Bediener zu kodieren.
  • Es ist einfach, eine Sitzung zu beenden, wenn sich jemand abmeldet.

Nachteile:

  • Die Serverseite muss regelmäßig abgelaufene Sitzungen löschen, bei denen sich der Client nicht abgemeldet hat.
  • Jede HTTP-Anforderung erfordert eine Suche nach dem Datenspeicher.
  • Der Speicherbedarf steigt, wenn mehr Benutzer aktive Sitzungen haben.
  • Wenn mehrere Front-End-HTTP-Server vorhanden sind, müssen alle auf die gespeicherten Sitzungsdaten zugreifen können. Dies könnte etwas mehr Arbeit bedeuten, als es auf einem Server zu speichern. Die größeren Probleme bestehen darin, dass der Datenspeicher zu einer einzigen Fehlerquelle wird und zu einem Engpass werden kann.

JSON-Web-Token (JWT)

Im zweiten Fall werden die Daten in einem JWT gespeichert, das statt auf dem Server weitergegeben wird.

Vorteile:

  • Die serverseitigen Speicherprobleme sind behoben.
  • Der clientseitige Code ist einfach.

Nachteile:

  • Die JWT-Größe kann größer als eine Sitzungs-ID sein. Dies kann sich auf die Netzwerkleistung auswirken, da diese in jeder HTTP-Anforderung enthalten ist.
  • Die im JWT gespeicherten Daten können vom Client gelesen werden. Dies kann ein Problem sein.
  • Die Serverseite benötigt Code, um JWTs zu generieren, zu validieren und zu lesen. Es ist nicht schwer, aber es gibt eine gewisse Lernkurve und die Sicherheit hängt davon ab.

    Jeder, der eine Kopie des Signaturschlüssels erhält, kann JWTs erstellen. Sie wissen möglicherweise nicht, wann dies geschieht.

    Es gab (gibt?) Einen Fehler in einigen Bibliotheken, der alle mit dem "none" -Algorithmus signierten JWTs akzeptierte, sodass jeder JWTs erstellen konnte, denen der Server vertrauen würde.

  • Um ein JWT vor Ablauf zu widerrufen, müssen Sie eine Widerrufsliste verwenden. Auf diese Weise kehren Sie zu den serverseitigen Speicherproblemen zurück, die Sie vermeiden wollten.

OAuth

Oft wird OAuth für die Authentifizierung (dh Identität) verwendet, aber es kann verwendet werden, um andere Daten wie eine Liste von Inhalten, die der Benutzer gekauft hat und die zum Herunterladen berechtigt sind, gemeinsam zu nutzen. Es kann auch verwendet werden, um Schreibzugriff auf Daten zu gewähren, die von Dritten gespeichert wurden. Sie können OAuth verwenden, um Benutzer zu authentifizieren und anschließend den serverseitigen Speicher oder JWT für die Sitzungsdaten zu verwenden.

Vorteile:

  • Kein Code für Benutzer, um sich anzumelden oder ihr Passwort zurückzusetzen.
  • Kein Code zum Senden einer E-Mail mit einem Validierungslink und anschließender Validierung der Adresse.
  • Benutzer müssen keinen anderen Benutzernamen und kein anderes Kennwort lernen / notieren.

Nachteile:

  • Sie sind auf den Dritten angewiesen, damit Ihre Benutzer Ihren Dienst nutzen können. Wenn ihr Service ausfällt oder sie ihn einstellen, müssen Sie etwas anderes herausfinden. Beispiel: Wie migrieren Sie die Kontodaten des Benutzers, wenn sich seine Identität von "[email protected]" zu "[email protected]" ändert?
  • Normalerweise müssen Sie Code für jeden Anbieter schreiben. zB Google, Facebook, Twitter.
  • Möglicherweise haben Sie oder Ihre Benutzer Datenschutzbedenken. Die Anbieter wissen, welche ihrer Nutzer Ihren Service nutzen.
  • Sie vertrauen dem Anbieter. Es ist für einen Anbieter möglich, Tokens, die für einen Benutzer gültig sind, an einen anderen Benutzer auszustellen. Dies kann aus rechtlichen Gründen erfolgen oder nicht.

Sonstiges

  • Sowohl Sitzungs-IDs als auch JWTs können von mehreren Benutzern kopiert und verwendet werden. Sie können die Client-IP-Adresse in einem JWT speichern und validieren. Dadurch wird jedoch verhindert, dass Clients beispielsweise über Wi-Fi zum Mobilfunknetz wechseln.
Chad Clark
quelle
Um Ihre Antwort zu ergänzen, ist oAuth möglicherweise nicht hilfreich, wenn sich Benutzer mit ihren Unternehmenskonten anmelden möchten, die normalerweise nicht mit den Websites sozialer Netzwerke oder Google verknüpft sind.
Aftab Naveed
5
Ich weiß nicht, warum dies die akzeptierte Antwort ist. es nicht die eigentliche Frage beantworten, sondern nur die Frage in anderer Art und Weise reformiert
amd
1
Sie sagen: "Die im JWT gespeicherten Daten können vom Client gelesen werden. Dies kann ein Problem sein. Warum nicht JWE verwenden, wenn dies ein Problem ist?
Silber
Diese Antwort verwirrt Äpfel und Orangen. Sie sollten diese nicht mit OAuth 2.0 (der "Authorization" -Spezifikation) vergleichen. Was OP wissen muss ist: "Resource Owner Password Flow" - Authentifizierung als Grant.
Onur Yıldırım
5

Fragen Sie sich, warum Sie das ursprüngliche Token ungültig machen müssen.

Ein Benutzer meldet sich an, ein Token wird generiert und die App geht.

Der Benutzer drückt auf Abmelden, ein neues Token wird generiert und ersetzt das ursprüngliche Token. Wieder ist alles in Ordnung.

Sie scheinen sich Sorgen um den Fall zu machen, in dem beide Token herumhängen. Was passiert, wenn sich der Benutzer abmeldet und dann mithilfe des angemeldeten Tokens eine Anfrage stellt? Wie realistisch ist dieses Szenario? Ist es nur ein Problem beim Abmelden oder gibt es viele mögliche Szenarien, in denen mehrere Token ein Problem sein können?

Ich glaube nicht, dass es sich lohnt, sich Sorgen zu machen. Wenn jemand Ihre verschlüsselten https-Daten abfängt und entschlüsselt, haben Sie viel größere Probleme.

Sie können sich einen zusätzlichen Schutz gewähren, indem Sie eine Ablaufzeit für das ursprüngliche Token festlegen. Wenn also gestohlen wird oder so, dann ist es nur für kurze Zeit gut.

Andernfalls müssten Sie Statusinformationen auf dem Server haben. Token nicht auf die Blacklist setzen, sondern die Signatur des aktuellen Tokens auf die Whitelist setzen.

Cerad
quelle
2
Wenn Sie davon ausgehen, dass einige Ihrer Clients böswillig sind, können Sie leicht feststellen, dass eine Sitzung kopiert und wiederverwendet wird, und Sie müssen dem auf dem Server entgegenwirken.
Michael Shaw
1
Schlechte Idee, dies kann später von einem Hacker verwendet oder einfach nur gezwungen werden ...
CROSP
2
Stellen Sie sich vor, ein Benutzer möchte sich von allen anderen Geräten abmelden. Die Verwendung von JWT ist nicht möglich.
amd
@amd nicht möglich? Was ist, wenn ich nonce = (zufällig) hinzufüge und wenn sich der Benutzer abmeldet, das nonce ersetzen. Scheint einfach und effektiv.
Simon B.
3

Sie können die von Ihnen erwähnten JWT-Probleme lösen, indem Sie zusammen mit dem Benutzer einen Salt-Wert speichern und das Salt als Teil des Tokens für den Benutzer verwenden. Wenn Sie dann den Token ungültig machen müssen, ändern Sie einfach das Salz.

Ich weiß, dass es ein paar Jahre her sind, aber ich würde das jetzt tatsächlich anders machen. Ich denke, ich würde sicherstellen, dass Zugriffstoken eine relativ kurze Lebensdauer haben, beispielsweise eine Stunde. Ich würde auch sicher sein, Aktualisierungstoken zu verwenden, die auf dem Server statusbehaftet sind, und wenn ich dann die Sitzung einer anderen Person beenden wollte, würde ich das Aktualisierungstoken widerrufen, indem ich es vom Server entferne. Nach einer Stunde würde der Benutzer abgemeldet und müsste sich erneut anmelden, um wieder Zugriff zu erhalten.

RibaldEddie
quelle
4
Aber auch hier wird es staatlich voll in diesem Fall, so was ist der Grund Salz zu erstellen oder einen anderen Ansatz verwenden, können Sie einfach speichern Token in der Tabelle und löschen , wenn sie für ungültig erklärt werden sollten
CROSP
2
Sie können auch basierend auf der Zeit ungültig machen.
RibaldEddie
Was ist in diesem Fall der Unterschied zwischen der Ablaufzeit? Wie kann ich das Token basierend auf der Uhrzeit ungültig machen, zu der der Benutzer sich vom mobilen Client abmelden möchte? In diesem Fall scheint es keine Möglichkeit zu geben, dass API zustandslos ist. Was ist die geeignetste und sicherste Lösung als?
CROSP
2
Am besten ist es, sich von einem einzelnen Gerät abzumelden, wenn Sie sicherstellen, dass Sie zusätzlich zum Salt eine clientId verwenden. Ich schlage vor, Sie werfen einen Blick auf die Oauth-JWT-Inhaberspezifikation.
RibaldEddie
Danke für die Antwort, aber ich verstehe nicht, warum ich OAuth in diesem Fall überhaupt verwenden soll.
CROSP