Description
Summary
When an OAuth2 Client sends a token to a downstream OAuth2 Resource Server, and the OAuth2 Resource Server returns an HTTP 401 response, I would like to prevent the OAuth2 Client from sending that same token in future requests (and instead retrieve a new token for future requests).
Currently, spring-security-oauth2-client provides good support for re-retrieving/refreshing tokens before they expire. However, spring-security-oauth2-client does not provide good support for re-retrieving/refreshing access tokens when they have become invalid for reasons other than expiration. A good signal that a token is no longer valid is when an OAuth2 Resource Server returns an HTTP 401 response to the client.
Both ServerOAuth2AuthorizedClientRepository
and ReactiveOAuth2AuthorizedClientService
provide a removeAuthorizedClient
method to remove the cached OAuth2AuthorizedClient
. It would be nice if spring-security-oauth2-client provided something that actually called that method when an HTTP 401 response is received from an OAuth2 Resource Server.
A possible implementation might be:
- the
DefaultReactiveOAuth2AuthorizedClientManager
(and the futureAuthorizedClientServiceReactiveOAuth2AuthorizedClientManager
from Reactive Implementation of AuthorizedClientServiceOAuth2AuthorizedCli… #7589) could put aMono<Void>
in the subscriber context that will remove the token from the cache when subscribedDefaultReactiveOAuth2AuthorizedClientManager
would put aMono<Void>
that invokes itsServerOAuth2AuthorizedClientRepository.removeAuthorizedClient
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager
would put aMono<Void>
that invokes itsReactiveOAuth2AuthorizedClientService.removeAuthorizedClient
- A new
ExchangeFilterFunction
(or one of the existing ones) checks for HTTP 401 responses, and chains theMono<Void>
from step 1 if it exists- usage of the subscriber context would decouple the
ExchangeFilterFunction
from the implementation of how to remove the cached authorized client (i.e. separate filter function implementations would not be needed depending on whether aServerOAuth2AuthorizedClientRepository
orReactiveOAuth2AuthorizedClientService
is being used to persistOAuth2AuthorizedClient
s) - It would also allow other places downstream (e.g. non-WebClient related functionality, like WebSocketClient) to potentially invalidate the authorized client, without direct knowledge of exactly how it is persisted, other than just subscribing to a
Mono<Void>
)
- usage of the subscriber context would decouple the
(After looking at this a bit more, I realize the above approach probably won't work, since anything put into the subscriber context by a ReactiveOAuth2AuthorizedClientManager
wouldn't actually be visible downstream in an ExchangeFilterFunction
. So, something else is needed. Perhaps something in ServerOAuth2AuthorizedClientExchangeFilterFunction
)
Actual Behavior
spring-security-oauth2-client continues to reuse an OAuth2 token, even after an OAuth2 Resource server has returned a 401 response, which usually indicates the token is invalid.
Expected Behavior
spring-security-oauth2-client removes the cached token after an OAuth2 Resource server has returned a 401 response. Future requests will trigger a re-retrieval of a new token.
Configuration
- spring-security-oauth2-client
- using either
DefaultReactiveOAuth2AuthorizedClientManager
orAuthorizedClientServiceReactiveOAuth2AuthorizedClientManager
from Reactive Implementation of AuthorizedClientServiceOAuth2AuthorizedCli… #7589 - WebClient or WebSocketClient usage downstream
Version
5.2.1.RELEASE