Single Sign-On-Flow mit JWT für die domänenübergreifende Authentifizierung

112

Im Internet gibt es viele Informationen zur Verwendung von JWT ( Json Web Token) zur Authentifizierung. Ich fand jedoch immer noch keine klare Erklärung für den Ablauf, wenn JWT-Token für eine Single Sign-On-Lösung in einer Umgebung mit mehreren Domänen verwendet werden .

Ich arbeite für eine Firma, die viele Websites auf verschiedenen Hosts hat. Verwenden wir example1.com und example2.com . Wir benötigen eine Single Sign-On-Lösung. Wenn sich ein Benutzer auf example1.com authentifiziert , soll er automatisch auch auf example2.com authentifiziert werden.

Mit Hilfe der OpenId Connect Flow, ich verstehe , dass der Benutzer, der authentifizieren will example1.com wird zunächst auf die umgeleitet werden Server - Authentifizierung (oder OP: „OpenID - Provider“). Der Benutzer authentifiziert sich auf diesem Server und leitet ihn dann mit einem signierten JWT-Token zurück zur ursprünglichen Website example1.com . (Ich verstehe, dass es einen anderen Fluss gibt, der ein Zwischen-Token zurückgibt , das später selbst gegen das echte JWT-Token ausgetauscht werden kann, aber ich denke nicht, dass dies für uns erforderlich ist.) ...

Jetzt ist der Benutzer wieder auf example1.com und wird authentifiziert! Er kann Anfragen stellen und das JWT-Token in einem AuthenticationHeader übergeben. Der Server kann das signierte JWT überprüfen und somit den Benutzer identifizieren. Nett!

Erste Frage :

Wie soll das JWT-Token auf dem Client gespeichert werden? Es gibt wieder viele Informationen darüber, und die Leute scheinen zuzustimmen, dass die Verwendung Web Storageeher der richtige Weg ist als ein gutes altes cookies. Wir möchten, dass die JWT zwischen den Neustarts des Browsers dauerhaft bleibt. Verwenden wir also Local Storagenicht Session Storage...

Jetzt kann der Benutzer seinen Browser neu starten und wird weiterhin auf example1.com authentifiziert , solange das JWT-Token nicht abgelaufen ist!

Wenn example1.com eine Ajax-Anfrage an eine andere unserer Domains stellen muss , würde dies meines Erachtens die Konfiguration von CORS ermöglichen. Unser Hauptanwendungsfall sind jedoch keine domänenübergreifenden Anfragen, sondern eine Single Sign-On-Lösung !

Daher die Hauptfrage:

Wie sollte nun der Ablauf aussehen , wenn der Benutzer zu example2.com geht und wir möchten, dass er mit dem bereits vorhandenen JWT-Token authentifiziert wird? Local Storagescheint keinen domänenübergreifenden Zugriff zuzulassen, daher kann der Browser das JWT-Token derzeit nicht lesen, um Anforderungen an example2.com zu stellen !

Sollte :

  • Der Benutzer wird erneut zum Authentifizierungsserver umgeleitet ? Wenn sich der Benutzer für example1.com authentifiziert hat , hat der Authentifizierungsserver möglicherweise ein Cookie für den Benutzer festgelegt, sodass diese neue Authentifizierungsanforderung für example2.com dieses Cookie verwenden kann, um festzustellen , ob der Benutzer bereits authentifiziert ist, und ihn sofort zurück zu example2.com umzuleiten mit dem gleichen JWT-Token?
  • Oder kann der Browser auf example2.com auf das JWT-Token zugreifen , ohne erneut zum Authentifizierungsserver wechseln zu müssen ? Ich sehe, dass es speicherübergreifende Lösungen gibt , aber sind diese weit verbreitet? Sind sie die vorgeschlagene Lösung für eine domänenübergreifende SSO-Umgebung?

Wir wollen nichts Besonderes, wir würden uns über die meist verwendete Lösung freuen!

Elektrotyp
quelle

Antworten:

28

Der Benutzer sollte erneut zum Authentifizierungsserver umgeleitet werden und ein neues Token (JWT) erhalten, das speziell für example2.com bestimmt ist. So funktionieren OpenID Connect und jedes andere domänenübergreifende Verbund-SSO-Protokoll.

Hans Z.
quelle
15
Aber ohne dass der Benutzer die Authentifizierungsdaten (z. B. Benutzername / Passwort) erneut senden muss, da es sich um SSO handelt, oder? Wie wird es gemacht? Sollte der Authentifizierungsserver beim ersten Mal ein Standard-Cookie für den Benutzer setzen, damit er automatisch authentifiziert werden kann, wenn dieser Benutzer von einer neuen Domäne zurück ist?
Elektrotyp
7
Was aber, wenn der Benutzer den Browser so konfiguriert hat, dass alle Cookies blockiert werden?
Christiaan Westerbeek
1
Ich denke, eine Warnung sollte über Cookies platziert werden, dass "die Website möglicherweise nicht richtig funktioniert, wenn Ihr Browser Cookies blockiert"
AnBisw
Die einmalige Anmeldung bedeutet nicht zwangsläufig, dass der Benutzer eine laufende Sitzung hat, die von einem Cookie verfolgt wird. Das definierende Merkmal ist, dass dieselben Anmeldeinformationen für denselben Identitätsanbieter erneut verwendet werden, um Zugriff auf verschiedene Anwendungen von Drittanbietern zu erhalten, dh es ist kein Cookie erforderlich. nur die Wiederverwendung der gleichen Creds
Hans Z.
34

Die Umleitung des Benutzers zum zentralen Authentifizierungsdienst, wenn der Benutzer nicht angemeldet ist, um Anmeldeinformationen anzufordern und ein neues Authentifizierungstoken auszustellen, ist das häufigste Szenario in Single Sign On-Systemen, die bekannte Protokolle wie oauth2 oder OpenIdConnect verwenden

Wenn dieses Schema jedoch domänenübergreifend verwendet wird, besteht der Hauptnachteil darin, dass der Benutzer jedes Mal umgeleitet und authentifiziert wird, wenn er aufgrund einer Richtlinie mit demselben Ursprung zu einer anderen Domäne navigiert : Das Zugriffstoken kann nicht zwischen Domänen geteilt werden ( example2.comkann nicht auf Daten zugreifen of example1.com), sodass die Zieldomäne den Benutzer als nicht authentifiziert behandelt und ihn zum zentralen SSO-Dienst umleitet.

Um zu verhindern, dass der Authentifizierungsdienst Anmeldeinformationen erneut anfordert, wird häufig ein Sitzungscookie (kein Zugriffstoken) verwendet. Es gibt jedoch eine Methode zum Freigeben von Daten zwischen Domänen mithilfe des Browsers localStorage / Cookies und eines Iframes, der auf eine Zwischendomäne verweist sso.example.com

  1. Um den Benutzer in zu authentifizieren example1.com, leiten Sie ihn zum Authentifizierungsserver in um sso.example.com, geben Sie nach der Authentifizierung eine JWT aus und speichern Sie sie im localStorage dieser Domäne. Leiten Sie den Benutzer anschließend zur Ursprungsdomäne example1.com um

  2. Erstellen Sie einen Iframe, auf den Sie example2.comzeigen sso.example.com. Der iframe in sso.example.com liest das JWT-Token und sendet eine Nachricht an die übergeordnete Seite

  3. Die übergeordnete Seite empfängt die Nachricht und erhält das angehängte Token, das mit dem SSO-Fluss fortgesetzt wird

Es gibt kein Problem mit der Richtlinie für denselben Ursprung, da sso.example.comder Zugriff auf localStorage möglich ist und die Kommunikation zwischen iframe und der übergeordneten Seite zulässig ist, wenn sich Ursprungs- und Zieldomänen erkennen (siehe http://blog.teamtreehouse.com/cross-domain-). Messaging-with-Postmessage )

Um die Entwicklung zu vereinfachen, haben wir kürzlich ein domänenübergreifendes SSO mit JWT unter https://github.com/Aralink/ssojwt veröffentlicht

Diese Methode ist perfekt mit SSO-Flows kompatibel. Dies ist nur eine Möglichkeit, das Authentifizierungstoken ohne Umleitungen freizugeben und unnötige Anmeldungen zu vermeiden, wenn die Domänen zusammengeschlossen sind

pedrofb
quelle
3
Abgesehen von dieser Lösung, die sich nicht an einen Standard hält, überschreitet man normalerweise bei domänenübergreifendem SSO administrative Grenzen, und in diesem Fall würde die Verwendung derselben JWT für beide Domänen die Möglichkeit für einen Anwendungseigner in einer Domäne eröffnen, sich als Benutzer in der anderen auszugeben Domain
Hans Z.
6
Danke @HansZ. Wir haben diese Lösung tatsächlich implementiert, um eine einzige Verwaltung mehrerer Domänen mit Dutzenden von Anwendungen und denselben Benutzern zu ermöglichen. Die Operation ist ähnlich wie bei Google (relativ gesehen)
pedrofb
2

Ich bin mir nicht sicher, ob dies Ihre Frage beantwortet, aber wenn Ihr Hauptziel Single Sign-On ist, würde ein einfacher Reverse-Proxy Ihr Problem lösen (zumindest der domänenübergreifende Speicher- Proxy ).

Also example1.com example2.com

würde so etwas werden

example.com/example1

example.com/example2

(Und von einer Benutzerseite ist dies normalerweise sauberer)

Wenn dies keine Option ist, müssen Sie möglicherweise festlegen, dass ein Benutzer, der sich in einer Domäne authentifiziert, AJAX / hidden iframes verwendet, um auch eine Authentifizierung mit den anderen Domänen zu erstellen (ggf. ein einmaliges Token per URL senden) ).

und wenn dies keine Option ist, müssen Sie möglicherweise auf Benutzername + PIN zurückgreifen, da die Browser die domänenübergreifende Interaktion immer strenger gestalten.

Tezra
quelle