Skip to content

Support refreshing OIDC ID Token #16253

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

Open
filiphr opened this issue Dec 10, 2024 · 4 comments
Open

Support refreshing OIDC ID Token #16253

filiphr opened this issue Dec 10, 2024 · 4 comments
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: enhancement A general enhancement

Comments

@filiphr
Copy link
Contributor

filiphr commented Dec 10, 2024

Expected Behavior

When using the @RegisteredOAuth2AuthorizedClient or OAuth2AuthorizedClient I would like to use the OIDC ID Token instead of the Access Token.

I would like to use the existing functionality around OAuth2AuthorizedClient and OAuth2AuthorizedClientRepository to leverage the persistence of the refresh token and the RefreshTokenOAuth2AuthorizedClientProvider which offers the functionality for refreshing a token.

Current Behavior

Currently, when using the @RegisteredOAuth2AuthorizedClient and OAuth2AuthorizedClient, we only have access to the Access Token and we can only refresh that one.

Context

How has this issue affected you?
What are you trying to accomplish?

We have our own applications, for which we support different OIDC providers thanks to Spring Security. There are some use cases for us where one of the applications is proxying requests to some of the other applications, and in this case the ID Token should be used when communicating over REST.

Additional examples

There are certain APIs that required the usage of the ID Token when communicating over REST instead of the Access Token.

E.g. According to the Google Get an ID token a Google-signed ID token is needed for the following use cases:

  • Accessing a Cloud Run service
  • Invoking a Cloud Run function
  • Authenticated a user to an application secured by Identity-Aware Proxy (IAP)
  • Making a request to an API deployed with API Gateway or Cloud Endpoints

What other alternatives have you considered?

Currently, we implemented a really ugly solution fully inspired by the OAuth2AuthorizedClientRepository, DefaultOAuth2AuthorizedClientManager and RefreshTokenOAuth2AuthorizedClientProvider.

We first get the OIDC ID Token from the current OidcUser and / or from a repository like the OAuth2AuthorizedClientRepository.
If the token is expired, we then use OAuth2AuthorizedClientRepository to get the OAuth2AuthorizedClient, then we get the refresh token and we do exactly what is being done in RefreshTokenOAuth2AuthorizedClientProvider, the refreshed ID Token is in id_token in the additional parameters in OAuth2AccessTokenResponse.
Once we get the refreshed ID Token, we store it in something similar like the OAuth2AuthorizedClientRepository

I think that it would be good if this was coming natively from Spring Security. If you are open to something like this I would be open in working on a contribution for this.
My current idea is to add an OidcIdToken in the OAuth2AuthorizedClient, expand RefreshTokenOAuth2AuthorizedClientProvider to allow to use a custom attribute in the OAuth2AuthorizationContext to determine which token we want to use (in order to check for the validity and do the refresh). This class will be responsible for parsing the id_token from the additional parameters from the OAuth2AuthorizationContext.

Of course, we need to review the other OAuth2AuthorizedClientProvider(s) to see which places might return an ID Token in addition to an access token.

@filiphr filiphr added status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Dec 10, 2024
@sjohnr
Copy link
Contributor

sjohnr commented Dec 17, 2024

Related gh-15509

@sjohnr
Copy link
Contributor

sjohnr commented Mar 18, 2025

Hi @filiphr. I wanted to get your thoughts on PR #16589. Specifically, I wonder if you feel that it has the potential to help with this issue?

The reason I ask is that with that PR, we would be publishing an event with the full OAuth2AccessTokenResponse (potentially containing an id_token parameter) along with the corresponding OAuth2AuthorizedClient when a refresh happens. This would allow an application to consume the event in a custom way (custom event listener) and persist/use ID tokens as needed. Do you feel this could be a solution (full or partial) for this issue?

By contrast, I am not sure whether Spring Security should support this issue directly. The reason I feel that way is that the framework does not have any use of an ID token outside of authentication, and the use of ID tokens for non-authentication purposes (at the client) are not defined in any specs I'm aware of. For example, you mentioned Google's use of ID tokens but I don't know of any specifications that govern those use cases. Are you aware of any related specs? If I'm correct that Google's uses are off-spec, I think it's fairly reasonable to build a custom solution such as yours. However, it could be made much nicer with the enhancement from #16589, which seems a decent tradeoff. What do you think?

@filiphr
Copy link
Contributor Author

filiphr commented Mar 18, 2025

Thanks for checking @sjohnr. The PR #16589 is a good one, especially when needing to access the current login registration.

However, I am not sure that it is enough, it only does a refresh when the access token has expired, so if the access token has a longer expiration time than the ID Token, then the PR will not help.

My main problem is that when using something like @RegisteredOAuth2AuthorizedClient I cannot get access to the ID Token, as the OAuth2AuthorizedClient does not contain it. The OAuth2AuthorizedClient already has a mechanism for persisting all the information that it contains.

For my particular use case I think that it would be more than enough if the additionalParameters from the OAuth2AccessTokenResponse are also part of the OAuth2AuthorizedClient. Then I can look into them and do what I need to do and convert the ID Token and check if it is valid or not and maybe refresh it on my own.

Perhaps we can change the issue to something like "Expose OAuth2AccessTokenResponse additionalParameters to OAuth2AuthorizedClient`

@sjohnr
Copy link
Contributor

sjohnr commented Mar 18, 2025

@filiphr, thanks. I hear what you're saying and it makes sense.

However, I am not sure that it is enough, it only does a refresh when the access token has expired, so if the access token has a longer expiration time than the ID Token, then the PR will not help.

If the ID token was part of the OAuth2AuthorizedClient, it would be fairly reasonable to create something like RefreshIdTokenOAuth2AuthorizedClientProvider. The only problem is I don't know of a spec that supports this. So we would be building custom functionality, and ideally we would support standard behavior and features when possible. I think something like this will always be custom when it is needed.

For my particular use case I think that it would be more than enough if the additionalParameters from the OAuth2AccessTokenResponse are also part of the OAuth2AuthorizedClient. Then I can look into them and do what I need to do and convert the ID Token and check if it is valid or not and maybe refresh it on my own.

Ok. Let's leave this open and see if we get some upvotes from others needing something similar.

Perhaps we can change the issue to something like "Expose OAuth2AccessTokenResponse additionalParameters to OAuth2AuthorizedClient`

We certainly could. I do think the title is accurate for what you're really after though. So in the interest of others finding it and upvoting it, I'm inclined to leave it as is.

@sjohnr sjohnr added in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 31, 2025
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: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants