How to Configure SSL In Spring Boot 2

How to Configure SSL In Spring Boot 2:-

In this post, we are going to learn How to Configure SSL in Spring Boot 2. There are two different ways to configure SSL in Spring Boot 2.

  1. Using Default Configurations.
  2. Using Custom Configurations.

One of the prerequisites to Configure SSL is to have an SSL Certificate.

We can generate an SSL certificate ourselves known as a self-signed certificate for the development. 

In production, you should use a certificate issued by a trusted Certificate Authority (CA). It gives you a certificate file basically which we need to use in our code.

We will see how we can use the Self Signed Certificate file to Configure SSL In Spring Boot 2.

SSL is a mandatory in production as it prevents unwanted attacks

Tools and Technologies Used:-

  • Java JDK 8 (1.8.0_152)
  • Spring Boot 2.0.4.RELEASE
  • Maven 3.5

Using Basic Configurations to Setup SSL In Spring Boot 2:-

Spring Boot provides a way to configure SSL . We can mention few properties in our application and we are good to go.

Let’s Check a few of the properties below.

server.port=8443
security.require-ssl=true
server.ssl.key-store-type=JKS
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=frugalis007
server.ssl.key-alias=tomcat

As you can see in above properties we have used JKS keystore file type and given the name as keystore.jks This is the Self Signed Certificate has been generated and its copied under src/main/resources folder in spring boot.

While generating the Self Signed Certificate it asks for the password and we set alias which we have added in our properties.

As 8080 is considered to be a non-SSL port, We have configured the server port as 8443, to follow a standard.

Now Create a rest Service and run your application, you will be able to access the application using HTTPS. This is the simplest way to configure  SSL in any Spring Boot applications. Let’s have a look at the advanced level of configurations

Using Custom Configurations to Setup SSL in Spring Boot 2:-

Lets have a look at what we want here . We want our Keystore password to be encrypted in properties file using our own custom encryptor .

For the above requirement we need to Customize the Spring Boot SSL configurations.In Order to customize Spring Boot SSL configurations we need to Implement WebServerFactoryCustomizer

Any bean implementing this interface will get a callback with the server factory before the server itself is started . We can customize the Port ,Address,Password of the embedded Server.

package com.frugalis.ssl.App;

import java.io.File;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import com.frugalis.common.PasswordDecryptor;

@Component
@Profile("prod")
public class CustomServletContainer implements
		WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Inject
    private PasswordDecryptor passwordDecrypt;

	@Value("${key-store}")
	private String keystoreFile;
	@Value("${key-alias}")
	private String keystoreAlias;
	@Value("${key-store-type}")
	private String keystoreType;
	@Value("${key-password}")
	private String keystorePass;
        @Value("${port}")
        private int tlsPort;

	public void customize(TomcatServletWebServerFactory factory) {

		factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

		@Override
		public void customize(Connector connector) {
		
		connector.setPort(8443);
                connector.setSecure(true);
                connector.setScheme("https");
                connector.setAttribute("keyAlias", "tomcat");
                connector.setAttribute("keystorePass", "password");

                File file = new File(keystoreFile);
                String absoluteKeystoreFile = file.getAbsolutePath();
                
                connector.setAttribute("keystoreFile", absoluteKeystoreFile);
                connector.setAttribute("clientAuth", "false");
                connector.setAttribute("sslProtocol", "TLS");
                connector.setAttribute("SSLEnabled", true);

                Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();

                proto.setSSLEnabled(true);
                proto.setKeystoreFile(keystoreFile);
                proto.setKeystorePass(keystorePass);
                proto.setKeystoreType(keystoreType);
                proto.setKeyAlias(keystoreAlias);
		}
		});
	}

    @PostConstruct
    public void ProcessPassword() {
          keystorePass = passwordDecrypt.decryptPassword(keystorePass);
    }  
}

We have Configured Profiling to enable SSL in production mode in Spring Boot 2 .

Note:- In  a typical commercial  production environment we basically don’t enable SSL in application level instead its preferred to enable in the VIP level . Let me know if you guys face any issues.