Przepływ logowania pojedynczego przy użyciu tokena JWT do uwierzytelniania między domenami

112

W sieci jest wiele informacji na temat używania JWT ( Json Web Token) do uwierzytelniania. Ale nadal nie znalazłem jasnego wyjaśnienia, jaki powinien być przepływ podczas używania tokenów JWT do rozwiązania pojedynczego logowania w środowisku wielu domen .

Pracuję dla firmy, która ma wiele witryn na różnych hostach. Użyjmy example1.com i example2.com . Potrzebujemy rozwiązania jednokrotnego logowania, co oznacza, że ​​jeśli użytkownik uwierzytelnia się w witrynie example1.com , chcemy, aby był on również uwierzytelniany automatycznie w witrynie example2.com .

Rozumiem, że korzystając z przepływu OpenId Connect użytkownik, który chce uwierzytelnić się w witrynie example1.com, zostanie najpierw przekierowany na serwer uwierzytelniania (lub OP: „OpenId Provider”). Użytkownik uwierzytelnia się na tym serwerze, który następnie przekierowuje go z powrotem do oryginalnej witryny example1.com z podpisanym tokenem JWT. (Rozumiem, że istnieje inny przepływ, który zwraca token pośredni, który sam można później wymienić na prawdziwy token JWT, ale nie sądzę, że jest to dla nas wymagane) ...

Teraz użytkownik jest z powrotem na example1.com i jest uwierzytelniony! Potrafi wysyłać żądania, przekazując token JWT w Authenticationnagłówku, a serwer jest w stanie zweryfikować podpisany JWT i dzięki temu jest w stanie zidentyfikować użytkownika. Miły!

Pierwsze pytanie :

W jaki sposób token JWT powinien być przechowywany na kliencie? Jest znowu wiele informacji na ten temat i wydaje się, że ludzie zgadzają się, że używanie Web Storagejest właściwą drogą, a nie starym dobrym cookies. Chcemy, aby token JWT był trwały między ponownymi uruchomieniami przeglądarki, więc używajmy Local Storage, a nie Session Storage...

Teraz użytkownik może zrestartować przeglądarkę i nadal będzie uwierzytelniany na example1.com , o ile token JWT nie wygaśnie!

Ponadto, jeśli example1.com musi wysłać żądanie Ajax do innej z naszych domen, rozumiem, że konfiguracja CORS na to pozwoli. Ale naszym głównym przypadkiem użycia nie są żądania międzydomenowe, ale rozwiązanie jednokrotnego logowania !

Dlatego główne pytanie:

Jaki powinien być teraz przepływ, jeśli użytkownik przejdzie do example2.com i chcemy, aby został uwierzytelniony przy użyciu tokena JWT, który już posiada? Local Storagewygląda na to, że nie zezwala na dostęp między domenami, więc w tym momencie przeglądarka nie może odczytać tokenu JWT w celu wysłania żądań do example2.com !

Powinien :

  • Czy użytkownik został ponownie przekierowany do serwera uwierzytelniania ? Gdy użytkownik uwierzytelnił się w witrynie example1.com , serwer uwierzytelniania mógł ustawić plik cookie dla użytkownika, więc to nowe żądanie uwierzytelnienia dla domeny example2.com może użyć tego pliku cookie, aby sprawdzić, czy użytkownik jest już uwierzytelniony i natychmiast przekierowuje go z powrotem do example2.com z tym samym tokenem JWT?
  • A może przeglądarka w witrynie example2.com może uzyskać dostęp do tokena JWT bez konieczności ponownego przechodzenia do serwera uwierzytelniania ? Widzę, że istnieją rozwiązania typu cross-storage , ale czy są one szeroko stosowane? Czy są one sugerowanym rozwiązaniem dla środowiska logowania jednokrotnego między domenami?

Nie chcemy niczego wyszukanego, bylibyśmy zadowoleni z najczęściej używanego rozwiązania!

elektrotyp
źródło

Odpowiedzi:

28

Użytkownik powinien zostać ponownie przekierowany do serwera uwierzytelniającego i uzyskać nowy token (JWT), który jest przeznaczony dla domeny example2.com. W ten sposób działa OpenID Connect i każdy inny międzydomenowy federacyjny protokół logowania jednokrotnego.

Hans Z.
źródło
15
Ale bez konieczności ponownego wysyłania przez użytkownika danych uwierzytelniających (na przykład nazwy użytkownika / hasła), ponieważ jest to SSO, prawda? Więc jak to się robi? Czy serwer uwierzytelniający powinien ustawić standardowy plik cookie dla użytkownika za pierwszym razem, aby mógł go automatycznie uwierzytelnić, gdy ten użytkownik wróci z nowej domeny?
elektrotyp
7
Ale co, jeśli użytkownik skonfigurował przeglądarkę tak, aby blokowała wszystkie pliki cookie?
Christiaan Westerbeek,
1
Wydaje mi się, że należy umieścić ostrzeżenie o
plikach
jednokrotne logowanie niekoniecznie oznacza, że ​​użytkownik ma trwającą sesję śledzoną przez plik cookie: jego cechą charakterystyczną jest ponowne wykorzystanie tych samych poświadczeń wobec tego samego dostawcy tożsamości w celu uzyskania dostępu do różnych aplikacji innych firm, tj. nie jest wymagany plik cookie, po prostu ponowne użycie tych samych kredytów
Hans Z.
35

Przekierowanie użytkownika do centralnej usługi uwierzytelniania, gdy użytkownik nie jest zalogowany, w celu zażądania poświadczeń i wydania nowego tokenu uwierzytelniania, jest typowym scenariuszem w systemach jednokrotnego logowania korzystających z dobrze znanych protokołów, takich jak oauth2 lub OpenId Connect

Jednak gdy ten schemat jest używany w różnych domenach, główną wadą jest to, że użytkownik będzie przekierowywany i uwierzytelniany za każdym razem, gdy przejdzie do innej domeny z powodu polityki tego samego pochodzenia : tokenu dostępu nie można udostępniać między domenami ( example2.comnie ma dostępu do danych of example1.com), więc domena docelowa będzie traktować użytkownika jako nieuwierzytelnionego, przekierowując go do centralnej usługi SSO.

Aby zapobiec ponownemu żądaniu poświadczeń przez usługę uwierzytelniającą, często stosuje się sesyjny plik cookie (nie token dostępu), ale istnieje technika udostępniania danych między domenami przy użyciu lokalnego magazynu / plików cookie w przeglądarce i ramki iframe wskazującej domenę pośrednią sso.example.com

  1. Aby uwierzytelnić użytkownika w programie example1.com, przekieruj go na serwer uwierzytelniający w sso.example.com, wystaw JWT po uwierzytelnieniu i zapisz go w localStorage tej domeny. Następnie przekieruj użytkownika do domeny źródłowej example1.com

  2. Utwórz ramkę iframe example2.comwskazującą na sso.example.com. Element iframe w sso.example.com odczytuje token JWT i wysyła komunikat do strony nadrzędnej

  3. Strona nadrzędna odbiera wiadomość i pobiera dołączony token kontynuujący przepływ logowania jednokrotnego

Nie ma problemu z polityką tego samego pochodzenia, ponieważ sso.example.comma dostęp do swojego localStorage, a komunikacja między iframe a stroną nadrzędną jest dozwolona, ​​jeśli domeny źródłowa i docelowa rozpoznają się nawzajem (patrz http://blog.teamtreehouse.com/cross-domain- messaging-with-postmessage )

Aby uprościć programowanie, udostępniliśmy niedawno międzydomenowe logowanie jednokrotne z JWT na https://github.com/Aralink/ssojwt

Ta metoda jest w pełni kompatybilna z przepływami SSO. To tylko sposób na udostępnienie tokenu uwierzytelniania bez przekierowań i uniknięcie niepotrzebnych logowania, gdy domeny są federacyjne

pedrofb
źródło
3
Oprócz tego rozwiązania niezgodnego ze standardem, zwykle w międzydomenowym SSO przekracza granice administracyjne iw takim przypadku użycie tego samego tokena JWT dla obu domen otworzyłoby właścicielowi aplikacji w jednej domenie możliwość podszywania się pod użytkownika w drugiej domena
Hans Z.
6
Dzięki @HansZ. W rzeczywistości wdrożyliśmy to rozwiązanie, aby mieć jedną administrację wieloma domenami z dziesiątkami aplikacji i tymi samymi użytkownikami. Operacja jest podobna do systemu Google (relatywnie rzecz biorąc)
pedrofb
2

Nie jestem pewien, czy to odpowiada na Twoje pytanie, ale jeśli Twoim głównym celem jest jednokrotne logowanie, myślę, że prosty zwrotny serwer proxy rozwiązałby Twój problem (przynajmniej w przypadku przechowywania danych między domenami).

A więc example1.com example2.com

stanie się czymś podobnym

example.com/example1

example.com/example2

(A po stronie użytkownika jest to zwykle czystsze)

Jeśli nie ma takiej opcji, może być konieczne skonfigurowanie tak, aby gdy użytkownik uwierzytelniał się w 1 domenie, używał AJAX / ukrytych ramek iframe do tworzenia uwierzytelnienia również w innych domenach (wysyłanie jednorazowego tokena za pośrednictwem adresu URL, jeśli trzeba ).

a jeśli to nie jest opcja, być może będziesz musiał skorzystać z nazwy użytkownika i kodu PIN, ponieważ przeglądarki są coraz bardziej rygorystyczne pod względem interakcji między domenami.

Tezra
źródło