-
Notifications
You must be signed in to change notification settings - Fork 6.3k
auth_time validation fails when SSO session is renewed #18839
Description
Describe the bug
The auth_time in the ID token is validated against the auth_time of the original access token in the session. But in some cases, this auth_time can be reset on the Identity Provider, resulting in an [invalid_id_token] Invalid authenticated at time on the client side whenever the token is refreshed.
Background
I ran into this bug when updating from Spring Boot 3.3.x to 3.5.x, so somewhere in the newer Spring Security version this validation has been added. Refreshing tokens has been working perfectly fine before, but after the update this error broke our code as we enforce authentication on other applications with prompt=login. I read the documentation of the OIDC specification and think that the current validation of the auth_time might be a little too strict. I am curious on what others would think of this situation.
To Reproduce
- Log in to a Spring Boot app via OIDC SSO
- Log in to another application on the same Identity Provider, but enforce entering credentials again with
prompt=login - Wait at least 5 minutes for the first access token to expire
- Try to refresh the token from the (first) Spring Boot app.
- Actual behavior: An
invalid_id_tokenerror pops up as theauth_timeof the refreshed ID token doesn't match theauth_timeof the original one within the application session.
Expected behavior
The tokens are refreshed, without any arror.
The OIDC specification mentions:
auth_time: Time when the End-User authentication occurred.
And also the requirements for a refreshed ID token:
if the ID Token contains an auth_time Claim, its value MUST represent the time of the original authentication - not the time that the new ID token is issued,
It might be debatable what 'time of original authentication' means here, but I would interpret that as: 'the time when authentication (for this new ID token) originated at the Identity Provider'. And as the Identity Provider only keeps track of one authentication session, that latest auth_time would be used here. Which is a perfectly valid for the refreshed ID token.
Spring Security wants to validate this auth_time after the ID token is being refreshed against the auth_time in the original ID token it received earlier. But I think it is not said in the specification that this should be done that way.
To fix this, Spring Security could either:
- remove the
validateAuthenticatedAtvalidation as you cannot know the time of the original authentication at this point. - or adapt it to only validate that it is earlier than the
issued_atof the newly refreshed ID token. As that is the only thing you can validate for certain at this point. - or make it configurable, so it can be disabled to allow auth_time changes.