【发布时间】:2021-10-14 18:49:53
【问题描述】:
我已经使用 oAuth2 成功实现了 WebClient。当身份验证服务器 (Keycloak) 具有 SSL (https) 时,oAuth2 面临问题。虽然我在定义 WebClient 时传递了 InsecureTrustManagerFactory,但在构建器完成之前调用了此 oAuth,因为它存在于过滤器中,它使用 WebClient 的默认实现并引发认证错误。
有没有办法我们可以配置 oAuth2 客户端也使用 InsecureTrustManagerFactory?
pom.xml 部分
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
Bean 配置
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
final ReactiveClientRegistrationRepository clientRegistrationRepository,
final ReactiveOAuth2AuthorizedClientService authorizedClientService) {
logger.info("ReactiveOAuth2AuthorizedClientManager Bean Method");
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder
.builder().password().build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
authorizedClientManager.setContextAttributesMapper(oAuth2AuthorizeRequest -> Mono
.just(Map.of(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, System.getProperty("user"),
OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, System.getProperty("pass"))));
return authorizedClientManager;
}
/**
* The Oauth2 based WebClient bean for the web service
*
* @throws SSLException
*/
@Bean
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) throws SSLException {
String registrationId = "bael";
SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
SslProvider sslProvider = SslProvider.builder().sslContext(sslContext).build();
HttpClient httpClient = HttpClient.create().secure(sslProvider)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000).responseTimeout(Duration.ofMillis(5000))
.doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS))
.addHandlerLast(new WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS)));
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager);
oauth.setDefaultClientRegistrationId(registrationId);
logger.info("WebClient Bean Method");
return WebClient.builder()
// base path of the client, this way we need to set the complete url again
.baseUrl("BASE_URL")
.clientConnector(new ReactorClientHttpConnector(httpClient))
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).filter(logRequest())
.filter(oauth).filter(logResponse()).build();
}
【问题讨论】:
标签: spring-boot spring-oauth2 spring-webclient