Search Tutorials


Spring Boot 3 - Enable HTTPS (SSL) Example| JavaInUse

Spring Boot 3 - Enable HTTPS (SSL) Example

In this Spring Boot example, you will be guided through the steps of configuring a web application to run on SSL (HTTPS) with a self-signed certificate. Setup for HTTPS with Spring Boot is a two-step process: obtaining an SSL certificate and then configuring SSL within the Spring Boot framework. Whether you are planning to generate a self-signed certificate or you already possess one issued from a Certificate Authority, I will illustrate how to enable HTTPS in a Spring Boot application.

Implementation

This tutorial will be divided in two parts -
  • Generate SSL certificate
  • Configure SSL for Spring Boot

Generate SSL certificate

A self-signed certificate is a type of SSL/TLS digital certificate that is signed by the same entity that created it, rather than a trusted certificate authority. While this approach can be used in production environments, it is not recommended due to the lack of trust verification and therefore potential security risks. If security is a priority for your application, it is recommended to obtain a certificate from a certificate authority (CA) instead.
In order to activate HTTPS, we must generate a set of cryptographic keys, put them to use for producing an SSL certificate, and then ensure it is properly stored in a keystore. According to the keytool documentation, a keystore is essentially a database stocked with "cryptographic keys, X.509 certificate chains, and validated certificates". To enable our Spring Boot application to take advantage of HTTPS capabilities, we must give it access to the keystore where the SSL certificate is stored. When it comes to keystores, two of the most prominent formats are JKS -- which is a format only used by Java -- and PKCS12, an industry-standard format. Although, historically, the JKS format was the default choice, since Java 9, PKCS12 has been the suggested format. This tutorial will walk you through how to take advantage of both options.

Generate JKS keystore

Following generates a cryptographic keypair and stores it under the alias of "javainuse" using the RSA encryption algorithm and a key size of 4096 bits. It then stores this keypair in a Java Keystore (JKS) file called javainuse.jks, with a validity period of 3650 days. Finally, the storepass parameter sets the password to access the JKS file as "javainuse".
keytool -genkeypair -alias javainuse -keyalg RSA -keysize 4096 -storetype JKS -keystore javainuse.jks -validity 3650 -storepass javainuse

Spring Boot 3 Security Spring Boot Security Java Keystore (JKS)

Generate PKCS12 keystore

Following generates a cryptographic keypair and store it under the alias of "javainuse" using the RSA encryption algorithm and a key size of 4096 bits. It then stores this keypair in a Public Key Cryptography Standards (PKCS12) file called javainuse.p12, with a validity period of 3650 days. Finally, the storepass parameter sets the password to access the PKCS12 file as "javainuse".
keytool -genkeypair -alias javainuse -keyalg RSA -keysize 4096 -storetype JKS -keystore javainuse.jks -validity 3650 -storepass javainuse

Spring Boot 3 Security PKCS12

Configure Spring Boot SSL with generated certificate

Create a spring boot project using Spring Initializr as follows -
Spring Boot 3 Security Spring Initializr
The final maven project will be as follows -
Spring Boot 3 SSL Project
The pom.xml will be as follows-
 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.1.1</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.javainuse</groupId>
	<artifactId>spring-boot-ssl</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-ssl</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
Create a Controller class to expose a GET API as follows-
package com.javainuse.springbootssl.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {

	@RequestMapping("/hello")
	public String hello() {
		return "Hello JavaInUse";
	}

}
Start the application using the SpringBootSslApplication class. If we now go to localhost:8080/hello we get the following-
Spring Boot 3 SSL Hello World
Next let us configure ssl for the application. For this copy the PKCS12 keystore which we created above to the resources folder. Next modify the application.properties as follows -
server.ssl.key-alias=javainuse
server.ssl.key-password=javainuse
server.ssl.key-store=classpath:javainuse.p12
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=PKCS12
If we now go to https://localhost:8080/hello we get the following.
Spring Boot 3 SSL https
But now suppose some user does not use https in the url and goes to localhost:8080/hello. We get the following error
Spring Boot 3 SSL exception
This should not be the case. In such a scenario, it should automatically redirect to https. In most scenarios https is set at port 443. So we will set the server port as 443.
server.ssl.key-alias=javainuse
server.ssl.key-password=javainuse
server.ssl.key-store=classpath:javainuse.p12
server.ssl.key-store-provider=SUN
server.ssl.key-store-type=PKCS12
server.port=443
Next create a configuration class for TomcatServletWebServerFactory, which is used to set up web servers in the Spring Framework. It adds a security constraint to the context, so that only authenticated users can access the web server. Lastly, it creates a connector to redirect requests from port 8080 to 443, ensuring that all communication with the web server is secured.
package com.javainuse.springbootssl;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WebConfig {

	@Bean
	public TomcatServletWebServerFactory servletContainer() {
		TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {

			@Override
			protected void postProcessContext(Context context) {
				SecurityConstraint securityConstraint = new SecurityConstraint();
				securityConstraint.setUserConstraint("CONFIDENTIAL");
				SecurityCollection collection = new SecurityCollection();
				collection.addPattern("/*");
				securityConstraint.addCollection(collection);
				context.addConstraint(securityConstraint);
			}
		};

		tomcat.addAdditionalTomcatConnectors(redirectConnector());
		return tomcat;
	}

	private Connector redirectConnector() {
		Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
		connector.setScheme("http");
		connector.setPort(8080);
		connector.setSecure(false);
		connector.setRedirectPort(443);

		return connector;
	}

}
Start the spring boot application. If we now go to localhost:8080 it will be automatically forwarded to https://localhost:443 i.e. https://localhost
Spring Boot 3 SSL redirect

Download Source Code

Download it -
Spring Boot 3 SSL Example