Spring Boot HTTPS with self-signed certificate

857 Views Asked by At

I'm making a Slack app with Spring Boot and have created an endpoint for Slack to send payloads to. Since Slack runs over HTTPS I have had to enable HTTPS by generating a self-signed certificate purely for testing purposes. I updated my application.yml with the following:

server:
  port: 3000
  ssl:
    enabled: true
    key-store: classpath:cert.p12
    key-store-password: my_password
    key-store-type: pkcs12

When I try to access the endpoint in my browser I get the error NET::ERR_CERT_INVALID. I then try curl on my endpoint and get the error:

curl: (60) SSL certificate problem: self signed certificate

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it.

My Slack app doesn't seem to be able to reach the endpoint either, giving an error /hello failed with the error "ssl_cacert" when I try a slash command.

Is there something else I need to do when setting up a self signed certificate? I'm aware this is unsafe in practice and therefore may be the root of these errors.

Many thanks for the help!

1

There are 1 best solutions below

0
On

First of all, you have to set up your backend correctly:

  1. Add dependency:

     implementation 'org.apache.httpcomponents:httpclient:4.5'    
    
  2. Provide RestTemplate bean:

@Bean
private RestTemplate restTemplate() {
        SSLContext sslContext = buildSslContext();
        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);

        HttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(socketFactory)
                .build();

        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);

        return new RestTemplate(factory);
    }

private SSLContext buildSslContext() {
        try {
            char[] keyStorePassword = sslProperties.getKeyStorePassword();
            return new SSLContextBuilder()
                    .loadKeyMaterial(
                            KeyStore.getInstance(new File(sslProperties.getKeyStore()), keyStorePassword),
                            keyStorePassword
                    ).build();
        } catch (Exception ex) {
            throw new IllegalStateException("Unable to instantiate SSL context", ex);
        } finally {
            sslProperties.setKeyStorePassword(null);
            sslProperties.setTrustStorePassword(null);
        }
    }
  1. Provide required SSL properties in your application.properties or application.yaml file:
server:
    ssl:
        enabled: true
        key-store: /path/to/key.keystore
        key-store-password: password
        key-alias: alias
        trust-store: /path/to/truststore
        trust-store-password: password

That's it. Now you can see your Tomcat is starting on 8080 (or another port) (https).

Alternatively, you can use my spring boot starter