3

I am trying to call a customer's endpoint to retrieve their data using WebClient. We have to use certificate when calling the endpoint. I configured the WebClient with filter (to handle auto-refresh of the access token) and also with httpclient taking the certificate as keyStore. However, I am getting the SSLHandshakeException. If I commented out the filter(oauth), then I didn't get the SSLHandshakeException. Can someone please let me know how to let ServerOAuth2AuthorizedClientExchangeFilterFunction work with the keyStore setup? Thanks.

@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();
 }

And the class making the call, where I am getting 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();
  }
jlp
  • 1,656
  • 6
  • 33
  • 48

0 Answers0