-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
WebClient support should get new access token when expired and password #8831
Comments
@FilipKittnar What I suspect is happening here is that a refresh token is returned on the initial call and associated to the OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.password()
.build(); It won't refresh the expired token because the I would try adding Regarding...
When the Give these 2 options a try and let me know if the issue is resolved. |
@jgrandja Hello, thanks a lot for your reply. Yes, I know, that the builder does not have a refreshToken configured. I was experimenting with that as well, it just wasn't in this snipped I posted here. |
@FilipKittnar |
Thanks for the tip. However, I'm still not totally sure from the documentation how to do it. Here's what I tried:
And here's, what heppened after I called the API after 30 minutes:
So it initialized the handler and did the removal. But then:
|
@FilipKittnar Based on your stacktrace, it looks like the behaviour is correct as the |
Oh, I get it! So when I call the API again after the refresh token expires, it will actually re-authenticate and get a new access token. So the actual recommended solution is to wrap the call in try-catch and if we get "Refresh token expired", we call the API again? Seems a little bit clunky, but it gets the job done. |
Just addition for others. If you use ServletOAuth2AuthorizedClientExchangeFilterFunction(OAuth2AuthorizedClientManager authorizedClientManager); then there is a note in javadoc:
And here is default implemenation of OAuth2AuthorizationFailureHandler authorizationFailureHandler =
new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(
(clientRegistrationId, principal, attributes) ->
authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal,
(HttpServletRequest) attributes.get(HttpServletRequest.class.getName()),
(HttpServletResponse) attributes.get(HttpServletResponse.class.getName()))); So I recommend to use another constructor ServletOAuth2AuthorizedClientExchangeFilterFunction(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientRepository authorizedClientRepository) which creates one ServletOAuth2AuthorizedClientExchangeFilterFunction servletOAuth2AuthorizedClientExchangeFilterFunction = new ServletOAuth2AuthorizedClientExchangeFilterFunction(defaultOAuth2AuthorizedClientManager);
servletOAuth2AuthorizedClientExchangeFilterFunction.setAuthorizationFailureHandler(defaultOAuth2AuthorizedClientManager.getAuthorizationFailureHandler()); and create a new default class new RemoveAuthorizedClientOAuth2AuthorizationFailureHandler(
(clientRegistrationId, principal, attributes) ->
authorizedClientRepository.removeAuthorizedClient(clientRegistrationId, principal,
(HttpServletRequest) attributes.get(HttpServletRequest.class.getName()),
(HttpServletResponse) attributes.get(HttpServletResponse.class.getName()))); |
The behaviour of Edit: turns out this is actually not the case. I just tested with a token lifespan of one minute and this is the default clock skew in Also, the "wrap the call into a try/catch and try again when the refresh token has expired" solution is not pretty, as it has to go to every call site or maybe a hand-written filter if that is possible. However, if I omit it, there will be an exception in my logfiles every 14 hours (our refresh token lifespan). Edit: this turned out to be easier than I though as well: |
Sorry to dig up this old ticket, but I think there is an inconsistency in the assumption made by Lines 100 to 107 in 0d71361
This piece of code assumes that there is a But that assumption is invalid in the general case, because there may be no call to Or, if you compare it to |
Describe the bug
I know this has been addressed and fixed before for client_credentials grant type: #5893 . Would it be possible to do the same for password grant type? I need to use the password grant type and it works but after 30 minutes the token expires and Spring Security does nothing about it and the API stops working and keeps returning 403 until I restart the whole application. Refresh token doesn't help because after that one expires, it just crashes on the expired refresh token and again, the API stops working until restart. I'm pretty sure that standard behavior would be to obtain new access token once it expires. When I switch to client_credentials grant type it works perfectly, but as I said, this grant type will be forbidden for me on production.
To Reproduce
application.yml:
MyClientConfig.java:
The API call itself:
Expected behavior
Get a new access token just before the expiration of the old one.
The text was updated successfully, but these errors were encountered: