Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication in the security context is not updated during the refresh token flow #15509

Open
ch4mpy opened this issue Aug 1, 2024 · 1 comment
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: bug A general bug

Comments

@ch4mpy
Copy link
Contributor

ch4mpy commented Aug 1, 2024

Describe the bug
Apparently, neither the ID token nor the userinfo are updated during the refresh token flow in Spring clients with oauth2Login. This has at least two consequences:

  • the principal (OidcUser or OAuth2User) might contain outdated data
  • in case of an RP-Initiated Logout, the OidcClientInitiated(Server)LogoutSuccessHandler might build a redirection URI to the authorization server end_session_endpoint with an expired or outdated ID token, in which case the second part of the logout fails and the user session on the OpenID Provider might not be ended.

Additional context about ID tokens
ID tokens are JWTs and, as with all JWTs, they expire.

ID tokens can be refreshed.

During RP-Initiated Logout, OpenID Providers SHOULD (not MUST) accept ID tokens even when the exp time has passed. This means that some OPs might not accept expired tokens and that clients would better do their best to send valid tokens.

Also, aside from expiration considerations, most OPs refreshing ID tokens accept only the last token they issued for a client. So when a new ID token is returned as part of a refresh token flow, the client should use this last issued ID token to build the RP-Initiated Logout location URI.

Last, I know no constraint in the specs about the different tokens relative lifespans. As a consequence, it seems possible that an ID token expires before the access one. And as far as I understood the source, the RefreshToken(Reactive)OAuth2AuthorizedClientProvider refreshes tokens only if the access token expired which leaves room for expired ID token in the security context.

To Reproduce
Using an authorization server refreshing ID token as part of the refresh token flow (Keyckloak is one, and, according to the Stackoverflow question linked below, Spring Authorization Server seems to be another):

  • login to an oauth2Client configured with oauth2Login and RP-Initated Logout
  • wait until the access token is expired
  • have refresh token flow executed. Using the (Reactive)OAuth2AuthorizedClientManager to retrieve the access token - like Spring Cloud Gateway TokenRelay= filter does - is enough.
  • initiate RP-Initiated Logout (send a POST request to the /logout endpoint)

Expected behavior

  • tokens should be refreshed if either the access or the ID token has expired (or will before the clockSkew)
  • if the security context contains an ID token (the principal is an OidcUser) and if the refresh token response contains an ID token, then the ID token in the security context should be updated
  • redirection to the authorization server end_session_endpoint should be built with the last issued ID token

The OidcClientInitiated(Server)LogoutSuccessHandler currently uses the (Reactive)ClientRegistrationRepository which doesn't trigger the refresh token flow in case of expired tokens. Shouldn't it use the (Reactive)OAuth2AuthorizedClientManager instead?

Some StackOverflow questions related to this issue:

@ch4mpy ch4mpy added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Aug 1, 2024
@ch4mpy ch4mpy changed the title OidcClientInitiated(Server)LogoutSuccessHandler might build a redirection URI to the authorization server end_session_endpoint with an expired ID token OidcClientInitiated(Server)LogoutSuccessHandler might use an expired ID token Aug 1, 2024
@sjohnr sjohnr self-assigned this Aug 23, 2024
@sjohnr sjohnr added the in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) label Aug 23, 2024
@sjohnr sjohnr moved this to Planning in Spring Security Team Aug 23, 2024
@ch4mpy
Copy link
Contributor Author

ch4mpy commented Aug 28, 2024

@sjohnr I think I progressed in my understanding of the root cause for this issue and re-wrote the description accordingly.

@ch4mpy ch4mpy changed the title OidcClientInitiated(Server)LogoutSuccessHandler might use an expired ID token OidcClientInitiated(Server)LogoutSuccessHandler might use an expired or outdated ID token Aug 28, 2024
@ch4mpy ch4mpy changed the title OidcClientInitiated(Server)LogoutSuccessHandler might use an expired or outdated ID token Authentication in the security context is not updated during the refresh token flow Sep 25, 2024
@sjohnr sjohnr removed the status: waiting-for-triage An issue we've not yet triaged label Oct 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: bug A general bug
Projects
Status: Planning
Development

No branches or pull requests

2 participants