1

I'm trying to build a REST client using Spring Boot and utilizing WebClient, however I'm conflicted when trying to config HTTPS call to a REST API.

When using RestTemplate, I was able to get self signed certificate working by using TrustSelfSignedStrategy(), thus even when the certificate is self signed, it is still being validated for its hostname, expiry date, etc.

In WebClient, so far I only found the way self signed certificate is by utilizing InsecureTrustManagerFactory, however this will cause the whole validation to be skipped as well, effectively void the purpose of using HTTPS in the first place.

As quoted from Netty documentations:

An insecure TrustManagerFactory that trusts all X.509 certificates without any verification.

NOTE: Never use this TrustManagerFactory in production. It is purely for testing purposes, and thus it is very insecure.

Is there any way I can use self signed certificate in WebClient without having to dismantle all the verification?

1 Answer 1

3

Yes, you can use a self signed certificate. What you need to do is add the self signed certificate into a java keystore and load it into your application by getting the keystore and transforming it into a TrustManager. Afterword you can supply the TrustManager to the SslContextBuilder which is needed for configuring the WebClient based on Netty. See below for an example:

Path truststorePath = Paths.get(/path/to/your/truststore)
InputStream truststoreInputStream = Files.newInputStream(truststorePath, StandardOpenOption.READ)

KeyStore truststore = KeyStore.getInstance(KeyStore.getDefaultType());
truststore.load(truststoreInputStream, truststorePassword);

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

SslContext sslContext = SslContextBuilder.forClient()
        .trustManager(trustManagerFactory)
        .build()

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

WebClient.builder()
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build()
Sign up to request clarification or add additional context in comments.

3 Comments

I reckon this method still enforce all the other verification; hostname, expiry, etc? I remember changing to InsecureTrustManagerFactory due to this can't seem to use self signed; however after some thought it might be caused by other things. I'll get back when I try this again. Thanks btw!
a little bit odd; This is due to the Certificate was not correctly prepared (hostname and CN was not matched - hence missing my whole purpose of this question), so I have some difficulty connecting it in dev env. I'm trying to test in pre-prod env with more proper certificate, hopefully today since I have requested the access from yesterday
result just comes in; it works. I will mark this as accepted answer, thank you very much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.