Skip to content

Instantly share code, notes, and snippets.

@chrisban
Last active February 7, 2023 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisban/362f43967d59b37b26e3ee7c18751eb0 to your computer and use it in GitHub Desktop.
Save chrisban/362f43967d59b37b26e3ee7c18751eb0 to your computer and use it in GitHub Desktop.
Create a Spring WebClient that is initialized with a public CA Cert and a chain of client cert and secret key
@Slf4j
@Configuration
@RequiredArgsConstructor
public class MTLSWebClient {
private final MtlsWebClientProperties mtlsWebClientProperties;
@Bean
public WebClient createMtlsWebClient() {
HttpClient httpClient = HttpClient.create().secure(t -> t.sslContext(
Objects.requireNonNull(getSSLContext())));
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
}
private SslContext getSSLContext() {
try {
// Identity store (client cert + private key via chain)
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(
getClass().getClassLoader().getResourceAsStream(mtlsWebClientProperties.keyStorePath),
mtlsWebClientProperties.keyStorePass.toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, mtlsWebClientProperties.keyStorePass.toCharArray());
// Trust store (public CA cert)
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(
getClass().getClassLoader().getResourceAsStream(mtlsWebClientProperties.trustStorePath),
mtlsWebClientProperties.trustStorePass.toCharArray());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
SSLFactory sslFactory = SSLFactory.builder()
.withIdentityMaterial(keyManagerFactory)
.withTrustMaterial(trustManagerFactory)
.build();
return NettySslUtils.forClient(sslFactory)
.build();
} catch (Exception e) {
log.error("Error creating mTLS WebClient. Check key-store / trust-store.");
e.printStackTrace();
}
return null;
}
}
@chrisban
Copy link
Author

chrisban commented Feb 7, 2023

Steps to generate the trust and identity stores:

Add CA cert to truststore:

keytool -importcert -storetype jks -alias truststore_alias -keystore truststore.jks -file ./some_cert.cer -storepass changeit

Add client cert/key to certificate chain:

cat ./some_cert.cer ./client.crt ./client.key.pem > client.chain.crt

Convert chain to PKCS12 format:

openssl pkcs12 -export -in client.chain.crt -out client.chain.p12 -password pass:"changeit" -name someclient-name -noiter -nomaciter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment