Overview
Most applications, even internal applications are being developed with increased focus on security. One of the basic steps is to host all web applications over secure channel. This post discusses how to enable SSL and client authentication in a Spring boot application.
The basic application structure
Before anything, the sample code is available here on Github. The application is a Spring Boot application exposing one endpoint /health. We would like to run this over SSL. We also want only registered clients to be able to connect to the server.
The security infrastructure
We need to generate a server SSL certificate to host the server on secure channel. We also need to generate a certificate for the client who wants to connect to the server. Once the client's certificate is generated, it must be added to the server's trust store so that the server accepts connections from any client who presents this certificate at connection time. The security settings to enable SSL are controlled entirely by settings present in the application.properties file:
server.ssl.enabled=true server.ssl.client-auth=need server.ssl.key-store=sec/server.p12 server.ssl.key-store-type=PKCS12 server.ssl.key-store-password=changeit server.ssl.key-alias=server server.ssl.trust-store=sec/server.p12 server.ssl.trust-store-password=changeit server.ssl.trust-store-type=PKCS12 server.ssl.protocol=TLS server.ssl.enabled-protocols=TLSv1.2
Building the code
You need to have JDK 8 or above. You need to have Maven 3. Both should be present on the machine's PATH. After downloading the source code, run the following command to build the code:
mvnw package
Running the server
Before the server can run successfully, we need to generate the servers certificate and a client certificate. The easiest way to do this is by running the gencerts.bat file. Create a folder named "sec" under the "target" folder which contains the built jar file. Copy the gencerts.bat file in the "sec" folder. Open a command prompt and navigate into the "sec" folder and execute the gencerts.bat file. It should generate the following files:
client.crt client.p12 server.crt server.p12 server.pem
Next, navigate back to the "target" folder containing the jar and run it:
java -jar server-0.0.1-SNAPSHOT.jar
Connecting to the server
We will use curl utility to connect to the server and invoke its endpoint. Since the server is protected using mutual authentication, we need to specify the client certificate else the server will reject the connection. The client (curl in this case) also need to trust the server's certificate explicitly since it's a self signed certificate. Navigate into the "sec" folder and run the following command to invoke the server endpoint:
curl https://localhost:8080/health/ --cert client.p12:changeit --cacert server.pemWe should see the server's response like this:
Uptime: : 1 minutes