By default ServletOAuth2AuthorizedClientExchangeFilterFunction for ClientCredentials uses RestTemplate to request OAuth token in a blocking way
See original GitHub issueSummary
When using ServletOAuth2AuthorizedClientExchangeFilterFunction
to perform oauth requests using the Spring Webflux WebClient the filter function utilizes a blocking call using RestTemplate which blocks the calling thread.
Actual Behavior
getTokenResponse at https://github.com/spring-projects/spring-security/blob/master/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java#L349 using the default DefaultClientCredentialsTokenResponseClient (https://github.com/spring-projects/spring-security/blob/master/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/reactive/function/client/ServletOAuth2AuthorizedClientExchangeFilterFunction.java#L119) blocks.
Expected Behavior
The setup of the request should never block.
Configuration
ClientRegistration is created like this:
ClientRegistration.withRegistrationId("registration") //
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) //
.tokenUri(uaaUrl + OAUTH_TOKEN_ENDPOINT) //
.clientAuthenticationMethod(ClientAuthenticationMethod.POST) //
.userInfoAuthenticationMethod(AuthenticationMethod.HEADER) //
.clientId(getClientId()) //
.clientSecret(getClientSecret()) //
.build()
actual usage of webclient then is like this
Mono<ClientResponse> clientMono = webclient.get()
.uri("https://somewhere")
.attributes(clientRegistrationId("registration")).accept(MediaType.APPLICATION_JSON_UTF8)
.exchange();
clientMono.subscribe(); // this call blocks while initially retrieving oauth token
Version
spring-security-oauth2-client:5.1.1.RELEASE
Sample
I can provide a sample if nescessary but don’t have one right now.
Issue Analytics
- State:
- Created 5 years ago
- Comments:8 (5 by maintainers)
My issue probably comes from the fact that my WebClient usage actually has little to do with the incoming requests. I’m just using it to resolve client credentials OAuth tokens, similar on how it was possible with the OAuth2RestTemplate.
I have no need to store any information in the request security context, rather I’d like to store them globally for my application (since the oauth details are not user specific), what would be my best option to enable this?
@FrzMe If your app is running in a Servlet environment than you have blocking behaviour regardless if you’re using
WebClient
in a reactive way. As an FYI,WebClient
does support blocking behaviour viawebclient.get().uri("somewhere") ....block()
.If you’re using
WebClient
in a servlet environment than you need to use it withblock()
. See this example.If you’re using
WebClient
in a fully reactive environment (eg. Netty) than you would not useblock()
and simply return aMono
orFlux
. See this example.Makes sense?