Introduction:
In this blog post, we'll explore how to secure a Spring Boot application by enabling SSL (Secure Sockets Layer) encryption. SSL ensures secure communication between clients and your application by encrypting the data transmitted over the network. We'll guide you through the process of setting up SSL in a java spring boot application step by step.SSL Secure Communication |
Step 1: Generate SSL Certificate
To enable SSL, we need an SSL certificate. We can generate a self-signed certificate using the Java keytool. Open a terminal or command prompt and execute the following command:[user]$ keytool -genkeypair -alias application -keyalg RSA -keysize 4096 -storetype PKCS12 -keystore application.p12 -validity 3650
This command generates a self-signed certificate named "application.p12" and sets
its validity to 3650 days (about 10 years). You'll be prompted to enter some
additional information like your company name, name and address details.
I will be using same certificate to convert it into PEM based crt and key file and use it another configuration for PEM. if you are okay with configuring the just one previous certificate ignore this part.
openssl pkcs12 -in application.p12 -nokeys -out client.crt openssl pkcs12 -in application.p12 -nocerts -nodes -out client.key
Step 2: Create a Spring Boot Application
Let's create a new Spring Boot application using the spring initializr. Go
to spring starter and generate a new project with the following
options:
- Project: gradle
- Language: Java
- Spring Boot: 3.1
- Group: com.wranto
- Artifact: spring-ssl-bundle
- Dependencies: Web
Sample gradle file:
plugins { id 'java' id 'org.springframework.boot' version '3.1.0' id 'io.spring.dependency-management' version '1.1.0' } group = 'com.wranto' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() }
Once the project is generated, import it into your favourite IDE.
Step 3: Configure SSL in Spring Boot
I will be using latest feature of SSL bundle added in Spring Boot 3.1 and If you are using Spring Boot version below Spring-Boot 3.1 then you can use following configuration.
Open the application.properties file and
add the following configuration:
server.port=8443 server.ssl.key-store-type=PKCS12 server.ssl.key-store=classpath:application.p12 server.ssl.key-store-password=your_password
With Spring Boot 3.1 you can configure SSL Bundle properties and can configure different certificate to one or more connections for e.g RestTemplate, Embedded server
Configuring SSL Bundles:
You can use below properties to configure SSL Bundle.
Spring.ssl.bundle.jks - can be used to configure bundles using Java keystore files.
Spring.ssl.bundle.pem - can be used to configure bundles using PEM-encoded text files
You can configure more than one bundle for these types with user-provided name. Using the same name we can configure different ssl configuration for different components.
We will configure JKS based certificate for the Spring boot embedded server and will configure another pem certificate for RestClient.
application.properties:
server.port=8443 server.ssl.bundle=server spring.ssl.bundle.jks.server.key.alias=application spring.ssl.bundle.jks.server.keystore.location=classpath:./certificates/application.p12 spring.ssl.bundle.jks.server.keystore.password=secret spring.ssl.bundle.jks.server.keystore.type=PKCS12 # Another ssl spring.ssl.bundle.pem.client.keystore.certificate=classpath:./certificates/client.crt spring.ssl.bundle.pem.client.keystore.private-key=classpath:./certificates/client.keyYou can use pem for clientside and pkcs for server also.
Step 4: Create a Controller
Create a new class named `ResourceController` in the com.wranto.springsslbundle package with the following content:
package com.wranto.springsslbundle.controller; import com.wranto.springsslbundle.service.ResourceService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor public class ResourceController { private final ResourceService resourceService; @GetMapping("/ssl") public String getRestResource() { return "Spring Boot SSL"; } @GetMapping("/remoteRestCall") public String remoteRestCall(){ return resourceService.someRemoteRestCall(); } }
Step 5: Create a Service
The below service will be calling a free api. It will be using the ssl certificate, but in real world scenario you can configure certificate provided by some ssl certificate provider.
package com.wranto.springsslbundle.service; import org.springframework.boot.ssl.SslBundles; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class ResourceService { private final RestTemplate restTemplate; public ResourceService(RestTemplateBuilder restTemplateBuilder, SslBundles sslBundles){ this.restTemplate = restTemplateBuilder.setSslBundle(sslBundles.getBundle("client")).build(); } public String someRemoteRestCall() { return this.restTemplate.getForObject("https://www.boredapi.com/api/activity", String.class); } }
Step 6: Test the Application
Run the Spring Boot application, and you should see the following log
message:
Tomcat started on port(s): 8443 (https) with context path ''
Now, open your browser and navigate to `https://localhost:8443/hello`. If
everything is set up correctly, you should see the message "Spring Boot SSL!"
displayed in your browser.
As its self signed-certificate chrome is going to show warning for you. But you can replace the certificate with some ssl provider certificate.
Conclusion:
In this blog post, we learned how to secure a Spring Boot application with
SSL. We generated a self-signed SSL certificate, configured SSL in our
Spring Boot application, and created a simple controller to test the secure
communication. SSL ensures that the data transmitted between the client and
server is encrypted and secure.