首页 > 解决方案 > Java Spring Security WebClient 与 ServerOAuth2AuthorizedClientExchangeFilterFunction 一起使用时抛出 SSLHandshakeException

问题描述

我正在尝试调用客户的端点以使用 WebClient 检索他们的数据。调用端点时我们必须使用证书。我为 WebClient 配置了过滤器(以处理访问令牌的自动刷新),还使用 ​​httpclient 将证书作为 keyStore。但是,我得到了SSLHandshakeException. 如果我注释掉filter(oauth),那么我没有得到 SSLHandshakeException。有人可以让我知道如何ServerOAuth2AuthorizedClientExchangeFilterFunction使用 keyStore 设置吗?谢谢。

@Configuration
public class MyConfig {
  @Bean
  ReactiveClientRegistrationRepository clientRegistrations() {
    ClientRegistration registration = 
      ClientRegistration.withRegistrationId("authProvider")
                        .tokenUri(tokenUri)
                        .clientId(clientId)
                        .clientSecret(clientSecret)
                        .scope(scope)
                        .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                        .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
                        .build();
    
      return new InMemoryReactiveClientRegistrationRepository(registration);
      }

    @Bean(name = "mybean")
    WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations) {

    ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = 
       new ServerOAuth2AuthorizedClientExchangeFilterFunction(
          new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
              clientRegistrations, 
              new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrations)));

    oauth.setDefaultClientRegistrationId("authProvider");

    KeyStore keyStore = KeyStore.getInstance("jks");
    keyStore.load(new ClassPathResource(keyStoreFilename).getInputStream(), keyStoreString.toCharArray());
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, keyStoreString.toCharArray());

    SslContext sslContext = SslContextBuilder.forClient().keyManager(keyManagerFactory).build();

    HttpClient httpClient = HttpClient.create().secure(sslSpec -> sslSpec.sslContext(sslContext)); 

    return WebClient
           .builder()
           .filter(oauth) // if I commented it out, then it was working fine                    
           .clientConnector(new ReactorClientHttpConnector(httpClient))
           .defaultHeaders(httpHeaders -> {
                  httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                  httpHeaders.setAccept(List.of(MediaType.APPLICATION_JSON));
                  httpHeaders.setBearerAuth(token);
                    })
          .build();
 }

和打电话的班级,我在哪里Caused by: java.lang.NumberFormatException: For input string: javax.net.ssl.SSLHandshakeException:

{
   ResponseEntity<String> responseEntity;
    try {
        responseEntity = webClient.post()
                .uri(url)
                .body(BodyInserters.fromValue(valueString))
                .retrieve()
                .toEntity(String.class)
                .block();
  }

标签: javaspring-webfluxspring-security-oauth2keystorespring-webclient

解决方案


推荐阅读