If the OAuth2AuthorizedClient.accessToken is expired for a client_credentials OAuth2AuthorizedClient.clientRegistration than the OAuth2AuthorizedClientArgumentResolver should handle getting a new access token.
This functionality already exists in ServletOAuth2AuthorizedClientExchangeFilterFunction.authorizeWithClientCredentials() (Servlet) and ServerOAuth2AuthorizedClientExchangeFilterFunction.authorizeWithClientCredentials() (Reactive).
NOTE: This functionality needs to be implemented in both the Servlet and Reactive OAuth2AuthorizedClientArgumentResolver.
Related #5893
I'll take this on. Thanks Joe!
Great, thanks @mkheck. Let me know if you have any questions along the way.
@mkheck and @jgrandja, a couple notes on this:
@fritzdj
Would it make sense for there to be a buffer period...
You will notice the accessTokenExpiresSkew member in both ServletOAuth2AuthorizedClientExchangeFilterFunction and ServerOAuth2AuthorizedClientExchangeFilterFunction...this accounts for the buffer / latency that can occur. This same logic needs to be implemented here.
This is because we end up needing to pass that access token around to different classes, causing unnecessary refactoring
After OAuth2AuthorizedClientArgumentResolver resolves the OAuth2AuthorizedClient, you don't necessarily need to pass OAuth2AuthorizedClient down your application stack/tiers. For example, you can auto-wire OAuth2AuthorizedClientService in a component in the service/data tier to lookup the OAuth2AuthorizedClient. Note: OAuth2AuthorizedClientRepository is meant to be used in web-tier and OAuth2AuthorizedClientService in service/data tier.
Does this approach work for you?
Thanks @jgrandja, this clears things up. I do still think we should be able to call the logic within that resolver using a bean on demand if desired though. This way you could create clients that are more self-contained and wouldn't need to add the resolver to the controller. Could we potentially have shared logic being used by both options?
@fritzdj I'm not sure I'm completely following your idea/suggestion. Can you provide more detail please.
For example, you can auto-wire OAuth2AuthorizedClientService in a component in the service/data tier to lookup the OAuth2AuthorizedClient
@jgrandja This makes sense to me, but you would still need to use OAuth2AuthorizedClientArgumentResolver to resolve OAuth2AuthorizedClient in web-tier first. My suggestion is to make things more self-contained in service/data tier by allowing OAuth2AuthorizedClientService to get new access tokens if needed. I think Spring should allow new access tokens to be retrieved either way (in service/data tier _OR_ web tier). We tried this with a custom service bean and it is working using some of the logic in OAuth2AuthorizedClientArgumentResolver. Sorry for getting a little off topic with this particular issue.
@fritzdj
We tried this with a custom service bean and it is working using some of the logic in OAuth2AuthorizedClientArgumentResolver. Sorry for getting a little off topic with this particular issue.
Can you please open a new issue so we can continue this there. Also, can you share the code in the new issue so we can get more into the details. Thanks.
I re-evaluated this issue and the requirements are not correct. The OAuth2AuthorizedClientArgumentResolver is not intended to act in the role of an OAuth Client, therefore, it is not responsible for refreshing/renewing expired access tokens. This responsibility belongs to the OAuth Client - to check the existing access token for expiry before it attempts to request a protected resource.
NOTE: This capability is implemented in ServletOAuth2AuthorizedClientExchangeFilterFunction and ServerOAuth2AuthorizedClientExchangeFilterFunction, which is used by WebClient and acts in the role of the OAuth Client.
The only responsibility for the OAuth2AuthorizedClientArgumentResolver is to resolve the existing OAuth2AuthorizedClient from the OAuth2AuthorizedClientRepository, if not available, than initiate the authorization grant flow to resolve a new OAuth2AuthorizedClient. _NOTE:_ This functionality already exists.
Given this, I'm going to close this ticket as invalid.
@kalyaniyerra Please see #6811 as the goal there is to allow better reuse of the existing logic in ServletOAuth2AuthorizedClientExchangeFilterFunction.
Most helpful comment
@fritzdj
You will notice the
accessTokenExpiresSkewmember in bothServletOAuth2AuthorizedClientExchangeFilterFunctionandServerOAuth2AuthorizedClientExchangeFilterFunction...this accounts for the buffer / latency that can occur. This same logic needs to be implemented here.After
OAuth2AuthorizedClientArgumentResolverresolves theOAuth2AuthorizedClient, you don't necessarily need to passOAuth2AuthorizedClientdown your application stack/tiers. For example, you can auto-wireOAuth2AuthorizedClientServicein a component in the service/data tier to lookup theOAuth2AuthorizedClient. Note:OAuth2AuthorizedClientRepositoryis meant to be used in web-tier andOAuth2AuthorizedClientServicein service/data tier.Does this approach work for you?