Skip to content

Instantly share code, notes, and snippets.

@barser
Forked from 62mkv/README.md
Created January 16, 2022 22:57
Show Gist options
  • Save barser/5836a6d21dde69de6b48014622d2a975 to your computer and use it in GitHub Desktop.
Save barser/5836a6d21dde69de6b48014622d2a975 to your computer and use it in GitHub Desktop.
How to add a custom trusted certificate for making HTTP requests against external sites

Thoughts on how to add trusted store for connection to external sites that use that certificate for HTTPS

Option 1: global configuration

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.

Option 2. Smart configuration

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)

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