AuthenticationPrincipalArgumentResolver has an outdated Authentication when OIDC ID Token is updated after refresh token
Hi,
In a plain oauth2Login() application (keycloak as IDP for example), after https://github.com/spring-projects/spring-security/pull/16589 has been implemented, consider the following example :
@PostMapping("/fast")
public Map<String, Object> getOidcUserPrincipal @AuthenticationPrincipal OidcUser principal1) {
var principal2 = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return principal1.getClaims();
}
Once the OidcUserRefreshedEventListener#onApplicationEventhas been triggered, it's already too late for the AuthenticationPrincipalArgumentResolverto get the updated value, as it's not aware of the OidcUserRefreshedEvent.
So in the example above, with a very short Access Token Lifespan (let's say 2 minutes), principal1 might get the "before" refresh ID Token, whereas principal2 has the up-to-date value.
Shoot the endpoint before the refresh happens, values are in sync, wait a little, they are out-of-sync and so on.
Hope this is clear.
Thanks
@mpalourdio Sorry but I don't fully understand the issue you are having.
Can you please put together a minimal sample or test that reproduces the issue and then I can look into it further.
Yup, not very clear, I admit.
AuthenticationPrincipalArgumentResolver is the "helper" that let us inject @AuthenticationPrincipal OidcUser xxxx as argument of a method in a controller (or whatever @Bean) like in my example.
The problem is: If a user tries to access the endpoint in which we inject @AuthenticationPrincipal OidcUser xxxx, and the OidcUserRefreshedEventListener must be triggered because of the IDP token refresh policy (one or 2 minutes lifespan), the OidcUser xxxxxx that is resolved as the method argument by AuthenticationPrincipalArgumentResolver, ie. @AuthenticationPrincipal OidcUser xxxx, will be resolved before OidcUserRefreshedEventListener#onApplicationEvent happens.
The consequence is that @AuthenticationPrincipal OidcUser xxxxx is outdated once we enter the method, because the listeners have been triggered after AuthenticationPrincipalArgumentResolver resolves @AuthenticationPrincipal OidcUser xxxx`
Why ? I suppose that before triggering all the OIDC refresh workflow, @AuthenticationPrincipal OidcUser xxxx is resolved very soon in order to be injected as method parameter.
Hope this is clearer.
@mpalourdio I now understand the issue but it's still not clear how your specific flow is working. This is why I asked in the previous comment:
Can you please put together a minimal sample or test that reproduces the issue and then I can look into it further.
If this is indeed a bug, then a test would need to be provided regardless as part of the fix. I'll wait on the sample or test and will then look into this further.
Just to clarify:
and the
OidcUserRefreshedEventListenermust be triggered because of the IDP token refresh policy
OidcUserRefreshedEventListener is ONLY triggered when a refresh_token grant flow is performed by the client. The refresh_token grant flow is triggered via RefreshTokenOAuth2AuthorizedClientProvider through an OAuth2AuthorizedClientManager.
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.