Jaki jest cel czasu wygaśnięcia tokena identyfikatora w OpenID Connect?

92

W OpenID Connect token dostępu ma czas ważności. W przypadku przepływu kodu autoryzacyjnego jest to zwykle krótkie (np. 20 minut), po czym należy użyć tokena odświeżania, aby zażądać nowego tokena dostępu.

ID tokena również ma czas ważności. Moje pytanie brzmi: jaki jest tego cel?

Dowolny czas wygaśnięcia tokena identyfikatora krótszy niż czas wygaśnięcia tokena odświeżania będzie oznaczać, że w końcu będziesz mieć wygasły token identyfikatora, ale ważny token dostępu.

Więc masz zamiar:

  • nadaj swojemu tokenowi ID wygaśnięcie dłuższe niż wygaśnięcie tokenu odświeżania lub
  • ustaw go na taki sam termin ważności jak token dostępu i podejmij jakąś akcję (co?), gdy wygaśnie lub
  • po prostu zużyj token ID w swoim kliencie przy odbiorze, a następnie zignoruj ​​czas wygaśnięcia po tym?

Specyfikacja OpenID Connect mówi tylko, że podczas walidacji tokenu identyfikatora

"The current time MUST be before the time represented by the exp Claim."

który (prawdopodobnie) obsługuje trzecią opcję powyżej.


EDYTOWAĆ

Ponieważ OpenID Connect opiera się na OAuth2, odpowiedź na dodatkowe pytanie poniżej można znaleźć w specyfikacji OAuth2, która mówi:

expires_in
     RECOMMENDED.  The lifetime in seconds of the access token.

Powiązane pytanie brzmi: kiedy wymieniasz kod autoryzacyjny na tokeny, ta sama specyfikacja mówi, że możesz otrzymać odpowiedź, taką jak:

{
 "access_token": "SlAV32hkKG",
 "token_type": "Bearer",
 "refresh_token": "8xLOxBtZp8",
 "expires_in": 3600,
 "id_token": "eyJhbG[...]"
}

Ale do czego odnosi się „expires_in” w tym przypadku? Token dostępu, token odświeżania czy token ID?

(Aby uzyskać informacje, IdentityServer3 ustawia to na czas wygaśnięcia tokenu dostępu).

Appetere
źródło

Odpowiedzi:

90

Odpowiadam na własne pytanie, ponieważ odkryłem, że niektóre z założeń stojących za moim pytaniem były błędne, więc łatwiej je tutaj wyjaśnić, niż ponownie napisać pytanie.

Token ID służy do udowodnienia Klientowi, że użytkownik jest uwierzytelniony i kim jest w rezultacie.

Kiedy Klient otrzyma token ID, zwykle robi coś takiego, jak konwertowanie go na ClaimsIdentity i utrwalanie tego, np. Przy użyciu pliku cookie.

Token ID musi stracić ważność w tym momencie użytkowania (co powinno być, ponieważ właśnie został wydany). Ale po tym nie jest ponownie używany, więc nie ma znaczenia, czy wygaśnie, gdy użytkownik nadal ma aktywną sesję. Klient ma potrzebne informacje uwierzytelniające i może z kolei wybrać własną politykę dotyczącą czasu trwania sesji, zanim użytkownik będzie musiał się ponownie zalogować.

Zadając to pytanie, założyłem błędnie, że token identyfikacyjny i token dostępu powinny być używane razem, a zatem oba muszą mieć ważne daty ważności. Jest to złe z różnych powodów:

  • Tokeny ID służą wyłącznie do uwierzytelniania klienta (jak opisano powyżej).
  • Tokeny dostępu nie mają nic wspólnego z Klientami. Służą one do dostępu do zasobów, a Klient obsługuje je tylko wtedy, gdy z kolei musi wywołać zasób.
  • Coś w rodzaju samodzielnej aplikacji MVC lub WebForms wymaga tylko tokena identyfikatora. Jeśli nie wywołuje zasobu zewnętrznego, nie ma do czego udzielić dostępu, więc nie ma tokenu dostępu.
Appetere
źródło
3
Czy masz jakieś referencje do tego? Eugenio twierdzi, że w swojej odpowiedzi możesz odświeżyć znacznik identyfikatora. Czy to prawda?
AndyD
6
Nie można odświeżyć tokena ID w sensie przedłużenia jego wygaśnięcia (w taki sposób, w jaki token dostępu można odświeżyć za pomocą tokena dostępu offline). Ale jeśli masz niewygasłą sesję uwierzytelniania z dostawcą OpenID Connect (np. Plik cookie po zalogowaniu się do IdentityServer3), to po powtórzeniu żądania logowania Dostawca może pominąć uwierzytelnianie (ponieważ pliki cookie mówią, że to zrobiłeś) i po prostu zwrócić nowy token identyfikacyjny (i token dostępu, jeśli jest wymagany). Działa to oczywiście tylko wtedy, gdy plik cookie ma dłuższą żywotność niż token identyfikacyjny.
Appetere
1
Chociaż możesz to zrobić, nie jestem pewien, czy jest to właściwe. Nie byłoby to również bezproblemowe dla użytkownika końcowego, ponieważ wymagałoby kilku przekierowań przeglądarki.
Kir
@Kir Jeśli korzystasz z aplikacji jednostronicowej JavaScript (SPA), wówczas pierwsza próba odnowienia tokenu dostępu byłaby zazwyczaj procesem w tle, więc użytkownik końcowy nie zostałby przerwany. Np. Jeśli interfejs API zasobu odpowiada, że ​​token dostępu wygasł, SPA wysyła żądanie w tle do serwera tożsamości w celu uzyskania nowego tokenu dostępu. Tylko jeśli to się nie powiedzie (ponieważ token ID wygasł), musisz poprosić użytkownika o ponowne zalogowanie. Zobacz przykład JavascriptImplicitClient pod adresem github.com/IdentityServer/IdentityServer3.Samples/tree/master/ ... na przykład kod.
Appetere
Możesz odświeżyć Id_token, jeśli obsługa dostawcy OIdC zwróci go z żądania Refresh_token. Zobacz stackoverflow.com/questions/41168304/ ... i stackoverflow.com/questions/41741982/ ...
Michael Freidgeim,
36

Musiałem się w to zagłębić z własnych powodów i napisałem, więc opublikuję tutaj, czego się nauczyłem ...

Najpierw odpowiem na pytanie, ryzykując stwierdzenie oczywistego: tokenowi ID nie można ufać, a jego zawartość należy zignorować, jeśli aktualny czas jest dłuższy niż czas, który upłynął. W odpowiedzi pytającego stwierdza się, że po wstępnym uwierzytelnieniu użytkownika token ID nie jest ponownie używany. Ponieważ jednak token identyfikatora jest podpisany przez dostawcę tożsamości, z pewnością przydatne w dowolnym momencie może być udostępnienie sposobu niezawodnego określenia, kim jest użytkownik, do innych usług, z których może korzystać aplikacja. Używanie prostego identyfikatora użytkownika lub adresu e-mail nie jest niezawodne ponieważ można go łatwo sfałszować (każdy może wysłać adres e-mail lub identyfikator użytkownika), ale ponieważ token OIDC ID jest podpisany przez serwer autoryzacji (który zwykle ma również tę zaletę, że jest stroną trzecią), nie można go sfałszować i jest znacznie bardziej niezawodny mechanizm uwierzytelniania.

Na przykład aplikacja mobilna może chcieć móc powiedzieć usłudze wewnętrznej bazy danych, kim jest użytkownik, który korzysta z aplikacji, i może to zrobić po krótkim okresie po początkowym uwierzytelnieniu, w którym to momencie wygasł identyfikator tokenu, w związku z tym nie może służyć do wiarygodnego uwierzytelnienia użytkownika.

Dlatego tak jak token dostępu (służący do autoryzacji - określając jakie uprawnienia posiada użytkownik) można odświeżyć, czy można odświeżyć ID Token (służący do uwierzytelniania - określając, kim jest użytkownik)? Zgodnie ze specyfikacją OIDC odpowiedź nie jest oczywista. W OIDC / OAuth istnieją trzy „przepływy” do pobierania tokenów, przepływ kodu autoryzacji, przepływ niejawny i przepływ hybrydowy (które pominę poniżej, ponieważ jest to wariant dwóch pozostałych).

W przypadku niejawnego przepływu w OIDC / OAuth żądasz tokenu identyfikatora w punkcie końcowym autoryzacji, przekierowując użytkownika w przeglądarce do punktu końcowego autoryzacji i dołączającid_token jako wartość response_typeparametru żądania. Niejawny Przepływ pomyślnym uwierzytelnieniu Response jest zobowiązany do obejmują id_token.

W przypadku przepływu kodu uwierzytelniania klient określa codejako wartość response_typeparametru żądania podczas przekierowywania użytkownika do punktu końcowego autoryzacji. Pomyślna odpowiedź zawiera kod autoryzacji. Klient wysyła żądanie do punktu końcowego tokena z kodem autoryzacyjnym i, zgodnie z OIDC Core Section 3.1.3.3 Successful Token Response, odpowiedź MUSI zawierać ID Token .

Tak więc w przypadku obu przepływów początkowo otrzymujesz token identyfikatora, ale jak go odświeżyć? Rozdział 12 OIDC: Używanie tokenów odświeżania zawiera następującą instrukcję dotyczącą odpowiedzi tokenu odświeżania:

Po pomyślnym sprawdzeniu poprawności tokenu odświeżania treść odpowiedzi jest odpowiedzią tokenu z sekcji 3.1.3.3, z tą różnicą, że może nie zawierać tokenu id_token .

To nie może zawierać identyfikator token, a ponieważ nie ma sposobu, aby zmusić go określono zawierać znacznik ID, należy założyć, że odpowiedź nie będzie zawierać identyfikator token. Z technicznego punktu widzenia nie ma więc określonego sposobu „odświeżenia” tokena identyfikatora za pomocą tokena odświeżania. Dlatego jedynym sposobem uzyskania nowego tokena identyfikatora jest ponowna autoryzacja / uwierzytelnienie użytkownika przez przekierowanie użytkownika do punktu końcowego autoryzacji i uruchomienie niejawnego przepływu lub przepływu kodu uwierzytelniającego, jak opisano powyżej. Specyfikacja OIDC dodaje promptparametr żądania do żądania autoryzacji, więc klient może zażądać, aby serwer autoryzacji nie monitował użytkownika za pomocą żadnego interfejsu użytkownika, ale przekierowanie nadal musi nastąpić.

Scott Willeke
źródło
Jeśli piszesz ogólne oprogramowanie do pracy z dowolnym dostawcą autoryzacji, nie możesz polegać na zwrocie id_token z odświeżania. Jednak jeśli pracujesz z określonym dostawcą (takim jak IdentityServer4), możesz sprawdzić jego możliwości i użyć id_token otrzymanego po żądaniu odświeżenia
Michael Freidgeim
Jak więc można odświeżyć id_token?
jwilleke
@jwilleke AFAIK, jak wspomniano powyżej, „jedynym sposobem na uzyskanie nowego tokena identyfikatora jest ponowna autoryzacja / uwierzytelnienie użytkownika poprzez przekierowanie go do punktu końcowego autoryzacji”
Scott Willeke
@MichaelFreidgeim Ciekawe, czy masz na myśli mechanizm Open ID Connect Discovery ? Jak dokładnie to robimy?
Scott Willeke
1
Dobra odpowiedź na temat „treść odpowiedzi o odświeżeniu może nie zawierać identyfikatora id_token”. Głosowano za. Nawiasem mówiąc, rozumiem, że specyfikacja OIDC pozostawia swobodę przy użyciu Refresh Token w celu uzyskania nowego tokenu ID: klient może to zrobić, określając „id_token” jako jeden z zakresów; ale nadal obowiązuje tutaj ogólna ostrożność, ponieważ to serwer uwierzytelniający podejmuje ostateczną decyzję, czy przestrzegać żądanego zakresu.
RayLuo
7

Jeśli dobrze rozumiem, zgodnie z tym i specyfikacją OpenID Connect Core 1.0 , sam token ID może być przechowywany w plikach cookie jako mechanizm utrwalania sesji i wysyłany z każdym żądaniem uwierzytelniania do Klienta. Klient może następnie zweryfikować token identyfikatora lokalnie lub za pośrednictwem punktu końcowego weryfikatora dostawcy (jeśli jest dostępny, tak jak robi to Google ). Jeśli token stracił ważność, powinien wysłać kolejne żądanie uwierzytelnienia, z wyjątkiem tego czasu z prompt=noneparametrem adresu URL. Upewnij się również, że w id_token_hintparametrze wysłano wygasły token identyfikatora , w przeciwnym razie dostawca może zwrócić błąd.

Tak więc wygaśnięcie prompt=nonetokena ID wydaje się naturalne, ale zapewnia, że ​​nowy token ID można uzyskać płynnie bez interwencji użytkownika (chyba że użytkownik zostanie wylogowany z tego OpenID).

Bez Morrowless
źródło
6

To ten sam cel: nie możesz użyć id_tokenpo wygaśnięciu. Główną różnicą jest to, że id_tokenjest strukturą danych i nie musisz wywoływać żadnych serwerów ani punktów końcowych, ponieważ informacje są zakodowane w samym tokenie. Zwykły access_tokenjest zwykle nieprzezroczystym artefaktem (takim jak identyfikator GUID).

Konsument id_tokenmusi zawsze zweryfikować (czas) jej ważność.

Nie jestem w 100% zaznajomiony z IS, ale myślę, że to wygoda. Zawsze powinieneś sprawdzić expreklamację.

Wygaśnięcie to tylko jedna z walidacji. id_tokensą również podpisane cyfrowo i jest to również weryfikacja, którą należy przeprowadzić.

Eugenio Pace
źródło
Dzięki Eugenio. Główne pytanie, które mam, dotyczy tego, co należy zrobić, gdy token identyfikacyjny wygaśnie? Pomyślałem (prawdopodobnie błędnie), że aby odnowić krótkotrwały token dostępu, MUSISZ użyć odświeżającego tokena. Ale jeśli token identyfikatora ma taką samą datę ważności jak token dostępu, natychmiast otrzymasz wygasły token identyfikacyjny, więc odświeżanie tokena dostępu wydaje się bezcelowe. Myślę, że czegoś tu brakuje!
Appetere,
1
Możesz użyć (nieodwołanego) refresh_token, aby uzyskać nowy access_token lub id_token. Lub po prostu jako użytkownik, aby się ponownie zalogować. id_tokens są logicznym odpowiednikiem access_tokens. Po prostu inny format.
Eugenio Pace
2
Według mojego ostatniego rozumienia, kiedy użytkownik ma uwierzytelnioną sesję z serwerem autoryzacji, kiedy token dostępu wygaśnie, przekierowanie 401 => 302 do serwera autoryzacyjnego otrzyma nowe tokeny dostępu i identyfikatora bez interwencji użytkownika. Ale w trybie offline, refresh_token zwróci tylko nowy access_token, który mówi, że określony użytkownik może uzyskać dostęp do niektórych zasobów. Nie może zwrócić id_token, ponieważ oznaczałoby to, że dany użytkownik jest uwierzytelniony, a nie w trybie offline.
Appetere
To byłaby świetna odpowiedź na pytanie, jaka jest różnica między id_token i access_token (szczególnie w przypadku używania tokenów nieprzezroczystych / referencyjnych). Skoncentruj się najpierw na odpowiedzi na pytanie, a następnie wyjaśnij, w jaki sposób używane są tokeny dostępu i tokeny identyfikacyjne?
Trent
5

Odświeżenie tokena oznacza, że ​​można go ponownie użyć do zażądania czegoś od serwera autoryzacyjnego (w tym przypadku OP - dostawcy OpenID-Connect) NAWET GDY UŻYTKOWNIK NIE JEST ZALOGOWANY. Zwykle zezwalasz na to tylko w przypadku ograniczonych zasobów i tylko wtedy, gdy użytkownik zaloguje się i zostanie uwierzytelniony co najmniej raz. Same tokeny odświeżania również powinny być ograniczone w czasie.

W przepływie niejawnym OIDC wywołujesz punkt końcowy autoryzacji
i otrzymujesz token identyfikatora w odpowiedzi wraz ze wszystkimi zakresami i wszystkimi informacjami o oświadczeniach.
Kolejne wywołania interfejsu API mają być wykonywane za pomocą przepływu kodu .
Niejawny przepływ ma na celu włączenie aplikacji tylko javascript lub tylko przeglądarki. Nie jest to aplikacja, która wchodzi w interakcję z serwerem.
Więc nawet jeśli istniał sposób na „odświeżenie” tego tokena, nie należy - ze względów bezpieczeństwa - pozwolić mu żyć zbyt długo. Zostanie skradziony i ponownie wykorzystany przez nieautoryzowanych użytkowników podszywających się pod ten identyfikator. W tym celu należy wymusić nowy login.

W przepływie kodu wywołujesz punkt końcowy autoryzacji OP i otrzymujesz kod autoryzacji (zwany również tokenem autoryzacyjnym lub w skrócie authcode). Powinno to wygasnąć podobnie jak id_token, który otrzymałeś w niejawnym przepływie, z tych samych powodów i nie może i nie powinien być odnawiany.

Twój interfejs użytkownika lub aplikacja następnie wywołuje punkt końcowy tokenu OP i odbiera (czasami po dalszej zgodzie użytkownika za pośrednictwem interfejsu użytkownika, aby zezwolić na korzystanie z posiadanych zasobów na serwerze OP):

  • Identyfikator id_token do uwierzytelniania - którego nigdy nie należy używać ponownie w wywołaniach serwera, chyba że jako podpowiedź przy wylogowywaniu się, gdy jego wygaśnięcie nie jest już ważne, dlatego z powyższych powodów należy pozwolić na wygaśnięcie i nigdy go nie odświeżać.
  • Access_token - który później, podczas wywoływania API, można przekazać do punktu końcowego UserInfo OP. Spowoduje to zwrócenie oświadczeń, a interfejs API może odpowiednio autoryzować.

Możesz odświeżyć ten access_token, ponieważ informuje on tylko API, jakie roszczenia ma użytkownik i jakie zasoby (według zakresów i żądań każdego zakresu) zgodził się udostępnić. Jak wyjaśniono powyżej, służy to umożliwieniu dostępu nawet wtedy, gdy użytkownik nie jest już zalogowany. Oczywiście nigdy nie chcesz pozwolić na odświeżenie id_token, ponieważ nie chcesz zezwalać na podszywanie się bez logowania.

pashute
źródło
2
To, co powiedziałeś o niejawnym przepływie, jest częściowo niepoprawne. Klient korzystający z niejawnego przepływu może uzyskać token dostępu oprócz tokenu identyfikatora i może używać tego tokenu dostępu do interakcji z serwerem.
Shaun Luttin
Istnieje powszechna praktyka, że ​​po wygaśnięciu id_token klient żąda nowych tokenów z serwera, dzięki czemu użytkownik nie musi ponownie autoryzować. Np. Patrz damienbod.com/2017/06/02/…
Michael Freidgeim
4

Chciałem opublikować tę odpowiedź jako komentarz, ale ponieważ nie byłem zbyt aktywny w StackOverflow, wydaje mi się, że publikuję ją jako alternatywną odpowiedź.

Używasz również id_tokenjako http://openid.net/specs/openid-connect-session-1_0.htmlid_token_hint próbując wylogować użytkownika z sesji . Szczerze mówiąc, nie sądzę, aby to naprawdę miało znaczenie, jeśli w tym momencie wygasła, ponieważ martwisz się tylko wylogowaniem określonego użytkownika.id_token

dgonee
źródło
4

TLDR;

Sprawdź poprawność tokenu ID, zanim zaufasz temu, co mówi.

Więcej szczegółów

Jaki jest cel czasu wygaśnięcia tokenu identyfikatora w OpenID Connect?

Celem jest umożliwienie klientowi walidacji tokenu identyfikatora, a klient musi zweryfikować token identyfikatora przed operacjami, które wykorzystują informacje tokena identyfikatora .

Ze specyfikacji niejawnego przepływu OpenID :

Jeśli którakolwiek z procedur walidacji określonych w tym dokumencie zakończy się niepowodzeniem, wszelkie operacje wymagające informacji, których walidacja nie powiodła się, MUSZĄ zostać przerwane, a informacje, których walidacja się nie powiodła, NIE WOLNO używać.

Aby to potwierdzić, dokumentacja Google OpenID Connect mówi o weryfikacji tokenu identyfikacyjnego:

Jedną z rzeczy, które sprawiają, że tokeny identyfikacyjne są przydatne, jest fakt, że można je przekazywać między różnymi składnikami aplikacji. Te składniki mogą używać tokenu identyfikatora jako lekkiego mechanizmu uwierzytelniania uwierzytelniającego aplikację i użytkownika. Ale zanim będziesz mógł użyć informacji w tokenie identyfikatora lub polegać na nich jako na potwierdzeniu, że użytkownik został uwierzytelniony, musisz je zweryfikować.

Tak więc, jeśli nasza aplikacja kliencka ma wykonać jakąś akcję w oparciu o zawartość tokena ID, musimy ponownie zweryfikować token ID.

Shaun Luttin
źródło