Expected Behavior

It should be possible to add custom params to the oauth2 token request body when using WebClientReactiveClientCredentialsTokenResponseClient but it currently is not.

Current Behavior

The non-reactive side of things has a way to customize the token request body (as mentioned here which links to docs here) by providing a Converter<OAuth2AuthorizationCodeGrantRequest, RequestEntity<?>> and passing it into setRequestEntityConverter on the client. However, there is no analogue for this feature on the reactive side.

WebClientReactiveClientCredentialsTokenResponseClient does let you set your own WebClient instance, but then in getTokenResponse it sets a body on the request that you can't modify (it calls a private static body method to build the request body). I was able to work around the issue by supplying my own implementation of ReactiveOAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest>, but it basically just copies the code inside of WebClientReactiveClientCredentialsTokenResponseClient. It would be nice to be able to modify the request without providing my own client implementation.

Context

Some oauth2 providers, such as Auth0, require you to send non-standard parameters, such as audience as part of the token request. This has been reported multiple times, and every GH issue has been closed saying that it is currently possible to modify the request. Yes, it is possible when using the non-reactive DefaultClientCredentialsTokenResponseClient but not when using the reactive WebClientReactiveClientCredentialsTokenResponseClient.

Comment From: jgrandja

@zpearce WebClient allows you to modify the ClientRequest and/or ClientResponse via an ExchangeFilterFunction. See ExchangeFilterFunction.ofRequestProcessor() for processing the outgoing ClientRequest and ExchangeFilterFunction.ofResponseProcessor for processing the incoming ClientResponse.

You would then configure WebClient with the custom ExchangeFilterFunction and finally supply the WebClient to WebClientReactiveClientCredentialsTokenResponseClient.

I'm going to close this issue as the solution mentioned above is the recommended approach to use.

Comment From: minionOfZuul

@jgrandja Thank you for your response. I left out an important part of my submission. I need to be able to access the current client registrationId in order to look up the correct audience to add to the body of the token request. With an ExchangeFilterFunction I don't have access to the client registration. On the non-reactive side my Converter would be passed the OAuth2ClientCredentialsGrantRequest which would give me access to the ClientRegistration. On the reactive side I don't get access to a OAuth2ClientCredentialsGrantRequest, but only the ClientRequest.

How would I query the ClientRequest for the current ClientRegistration? Does it get added to the reactor Context?

Comment From: jgrandja

You could override WebClientReactiveClientCredentialsTokenResponseClient.getTokenResponse() and populate the reactor context with OAuth2ClientCredentialsGrantRequest or OAuth2ClientCredentialsGrantRequest.getClientRegistration() and then call super().

Alternatively, you could use a delegation-based strategy where the delegator would populate the reactor context and delegate to WebClientReactiveClientCredentialsTokenResponseClient.