Thoughts on how to add trusted store for connection to external sites that use that certificate for HTTPS
One can just provide the -Djavax.net.ssl.trustStore=<path/to/store> -Djavax.net.ssl.trustStorePassword=<password>
options when running the Java application
However, this is not always possible (for example, when run in the cloud).
And if you want to use server.ssl.trust-store/server.ssl.trust-store-password
options from Spring Boot, be aware that with
those you also have to provide key-store
options as well. And, basically that would be an abuse, because this configuration is specifically for server side of your application.
There's an alternative: provide custom properties, that can be overridden via environment variables, and add a bean to process those:
@ConfigurationProperties("client-ssl")
@Data
public class SslClientProperties {
private String trustStore;
private String trustStorePassword;
}
@Configuration
public class SslConfiguration {
public SslConfiguration(SslClientProperties properties) {
if (properties != null) {
if (StringUtils.isNotBlank(properties.getTrustStore()) {
System.setProperty("javax.net.ssl.trustStore", properties.getTrustStore());
}
if (StringUtils.isNotBlank(properties.getTrustStorePassword()) {
System.setProperty("javax.net.ssl.trustStorePassword", properties.getTrustStorePassword());
}
}
}
}
with this solution, however, one must pay attention that this configuration has to be initialized BEFORE the SSLEngine from the underlying server implementation.
When using a WebClient, we might customize specifically our WebClient by providing necessary config along the lines of:
@Configuration
public class WmsClientConfiguration {
@Bean
public WebClient.Builder jdaWmsBuilder() {
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(builder -> builder.sslSupport(sslContextBuilder -> {
Collection<X509Certificate> certs = getTrustedCerts();
sslContextBuilder.trustManager(certs.toArray(new X509Certificate[certs.size()]));
})));
}
}
(as of how getTrustedCerts
method might be implemented, see here: spring-projects/spring-boot#6493 (comment))
(WARNING: this has not been tested yet)
Great content. I wonder if I want to setup mutual TLS between two spring boot applications, then how should I set up the keystore on the client side? I guess using server.ssl.key-store is also an abuse because it is meant for the server side. I also tried with -Djavax.net.ssl.trustStore, Both do not work. T_T Maybe only the configuration is not enough? I don't if and how should I change the code for the client to be able to use its keystore and to provide the server its certificate.
Thank in advance for the help.