Configuring TLS with WebClient and netty

It is not intuitive that there is some work to do to get WebClient to communicate with certs. Having written this twice now across two projects, here it is:

// Pull these in however you like
@Value("${user.keystore}")
String keyStoreLocation;

@Value("${user.keystore.passwd}")
String keyStorePassword;

@Value("${user.truststore}")
String trustStoreLocation;

@Value("${user.truststore.passwd}")
String trustStorePassword;

...

HttpClient httpClient = HttpClient.create().secure(spec ->
{
  try {
    KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(new FileInputStream(ResourceUtils.getFile(keyStoreLocation)), keyStorePassword.toCharArray());

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());

    KeyStore trustStore = KeyStore.getInstance("JKS");
    trustStore.load(new FileInputStream((ResourceUtils.getFile(trustStoreLocation))), trustStorePassword.toCharArray());

    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(trustStore);

    spec.sslContext(SslContextBuilder.forClient()
      .keyManager(keyManagerFactory)
      .trustManager(trustManagerFactory)
      .build());
  } catch (Exception e) {
    logger.error("Unable to set SSL Context", e); 
  }
});

WebClient webClient = WebClient.builder()
  .baseUrl(baseUrl)
  .clientConnector(new ReactorClientHttpConnector(httpClient))
  .build();

Given a key and truststore, build an ssl context inside an httpClient, and pass that to your WebClient.

Apparently you can also do this with JVM options:

-Djavax.net.ssl.keyStore=<path>/keystore.jks
-Djavax.net.ssl.keyStorePassword=<password>
-Djavax.net.ssl.trustStore=<path>/truststore.ts
-Djavax.net.ssl.trustStorePassword=<password>
-Djavax.net.ssl.trustStoreType=JKS
-Dio.netty.handler.ssl.noOpenSsl=true

I have not personally tried this.

Now you don't have to go dig through forum threads and github tickets.