I'm using spring boot 3.3.1/spring security with oauth2. My Oauth2 / OIDC Provider is behind an Http Proxy. I need to customize the WebClient, in order to configure the HttpProxy.
Following the documentation, i have created 2 beans :
@Bean
public ReactiveOAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authorizationCodeAccessTokenResponseClient() {
WebClientReactiveAuthorizationCodeTokenResponseClient accessTokenResponseClient =
new WebClientReactiveAuthorizationCodeTokenResponseClient();
accessTokenResponseClient.setWebClient(webClient());
return accessTokenResponseClient;
}
@Bean
public ReactiveOAuth2AccessTokenResponseClient<OAuth2RefreshTokenGrantRequest> refreshTokenAccessTokenResponseClient() {
WebClientReactiveRefreshTokenTokenResponseClient accessTokenResponseClient =
new WebClientReactiveRefreshTokenTokenResponseClient();
accessTokenResponseClient.setWebClient(webClient());
return accessTokenResponseClient;
}
private static WebClient webClient() {
final HttpClient httpClient = HttpClient.create().proxyWithSystemProperties();
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
}
When the application receive the authorization code, spring security call the token endpoint and receive the access token. The custom bean WebClientReactiveAuthorizationCodeTokenResponseClient is used.
But when spring security call the endpoint to refresh the token, it doesn't work. The custom WebClientReactiveAuthorizationCodeTokenResponseClient is not used.
I put some breakpoint, the second bean is instantiated but in method RefreshTokenReactiveOAuth2AuthorizedClientProvider.authorize, the accessTokenResponseClient is not my custom bean, but the default one :
@Override
public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizationContext context) {
return Mono.just(refreshTokenGrantRequest)
.flatMap(this.accessTokenResponseClient::getTokenResponse) // <------ accessTokenResponseClient is the default one
.onErrorMap(OAuth2AuthorizationException.class,
(e) -> new ClientAuthorizationException(e.getError(), clientRegistration.getRegistrationId(), e))
.map((tokenResponse) -> new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(),
tokenResponse.getAccessToken(), tokenResponse.getRefreshToken()));
The workaround i found is to apply the configuration that should be used prior to 6.3 'Customize WebClient for OAuth2 Client (prior to 6.3') and publish a bean of type ReactiveOAuth2AuthorizedClientManager
Comment From: sjohnr
Hi @alexist, thanks for trying the feature and thanks reaching out!
I am not able to reproduce the issue with the information provided. Is it possible that spring-cloud-gateway-server (Spring Cloud Gateway) on the classpath in your application? This is usually added via the org.springframework.cloud:spring-cloud-starter-gateway dependency. If so, please see spring-cloud/spring-cloud-gateway#3493 which may be related.
Otherwise, can you please provide a minimal, reproducible sample to help me find the issue?
Comment From: alexist
Hi,
You're right, my project use spring-cloud-starter-gateway.
Thanks for the issue link
Comment From: sjohnr
The linked issue in Spring Cloud Gateway (https://github.com/spring-cloud/spring-cloud-gateway/issues/3493) has been resolved. I'm going to close this issue as a duplicate. Please try again either on snapshots of Spring Cloud Gateway, or once the next minor release of gateway is available. If you feel I've missed anything please let me know and we can re-open if necessary.