swirl
Home Software Blog Wallpapers Webtools
Enabling SSL and Client auth on Tomcat
Wednesday 10, July 2024   |   Post link

Overview

This blog post discusses how to enable SSL and client authentication in Tomcat 9.

A sample REST application

This post will make use of a Book API web application deployed on Tomcat to demonstrate how SSL and client auth can be used to access the books API.

Pre-requisites

  1. JDK 8
  2. Download Tomcat 9
  3. Download the Books API source code.
  4. OpenSSL (Windows version can be downloaded here.

Build the Books API application

Unzip the books-api-src.zip file to any folder. Build the source code using an IDE like IDEA IntelliJ or using Maven

When done correctly, you should get a books.war files generated in the taget directory.

Deploy the books application

Copy the books.war file to Tomcat's webapp directory. You should then be able to access the API using a url like http://localhost:8080/books/api/books.

At this point Tomcat is not using SSL.

Enabling SSL on Tomcat

Open a command prompt, change the directory to the conf folder of Tomcat. First thing to do is create a self-signed certificate for our server.

keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore server.p12 -validity 3650 -ext SAN=dns:localhost,ip:127.0.0.1 -dname "CN=localhost" -storepass changeit

The next step is to edit the server.xml present in Tomcat's conf folder to enable SSL:

<Connector 
    protocol="org.apache.coyote.http11.Http11NioProtocol"
    port="8443" maxThreads="200"
    maxParameterCount="1000"
    scheme="https" secure="true" SSLEnabled="true"
    keystoreFile="conf/server.p12" 
    keystorePass="changeit"
    clientAuth="false" sslProtocol="TLS" 
/>

Restart tomcat. Tomcat is not ready to accept SSL traffic on port 8443. We can now access the api at https://localhost:8443/books/api/books. The same can be done using curl:

curl https://localhost:8443/books/api/books -k

We should get a response like:

[{"id":1,"title":"IT","author":"Stephen King","cost":300.0},{"id":2,"title":"Different Seasons","author":"Stephen King","cost":250.0},{"id":3,"title":"Robot Dreams","author":"Isaac Asimov","cost":450.0},{"id":4,"title":"I, Robot","author":"Isaac Asimov","cost":350.0}]

Enabling certificate based client authentication

By enabling client authentication we force any client connecting to Tomcat to present a certificate which is trusted by the server. Any client failing to do so is not allowed to connect. To enable this, we need to do a couple of things.

Let's first create a self-signed client certificate:

keytool -genkeypair -alias client -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore client.p12 -validity 3650 -ext SAN=dns:localhost,ip:127.0.0.1 -dname "CN=localhost" -storepass changeit

Next, create a public certificate from the client's certificate:

keytool -export -alias client -file client.crt -keystore client.p12 -storepass changeit

Next, we create a truststore for our server, this is where client certificates which Tomcat will trust will be stored.

keytool -import -alias client -file client.crt -keystore truststore.p12 -storepass changeit -noprompt

Next step is to import the client's certificate into the truststore:

keytool -import -alias client -file client.crt -keystore truststore.p12 -storepass changeit -noprompt

We now need to reconfigure Tomcat to use the truststore. Edit the server.xml file to have the following content for the SSL connector:

<Connector 
    protocol="org.apache.coyote.http11.Http11NioProtocol"
    port="8443" maxThreads="200"
    maxParameterCount="1000"
    scheme="https" secure="true" SSLEnabled="true"
    keystoreFile="conf/server.p12"
    keystorePass="changeit"		   
    clientAuth="true" sslProtocol="TLS" 
	truststoreFile="conf/truststore.p12" 
    truststorePass="changeit"
/>	

Restart Tomcat. If we try to access the API using curl:

curl https://localhost:8443/books/api/books -k

We get an error:

curl: (35) schannel: next InitializeSecurityContext failed: SEC_E_CERT_UNKNOWN (0x80090327) - An unknown error occurred while processing the certificate.

So, we are required to pass a client certificate. We do this by using the following command:

curl https://localhost:8443/books/api/books --cert client.p12:changeit -k

And .. we get the response from the API:

[{"id":1,"title":"IT","author":"Stephen King","cost":300.0},{"id":2,"title":"Different Seasons","author":"Stephen King","cost":250.0},{"id":3,"title":"Robot Dreams","author":"Isaac Asimov","cost":450.0},{"id":4,"title":"I, Robot","author":"Isaac Asimov","cost":350.0}]

Hope this post was useful, until next time ... Bye!




Comments

Posts By Year

2024 (4)
2023 (5)
2022 (10)
2021 (5)
2020 (12)
2019 (6)
2018 (8)
2017 (11)
2016 (6)
2015 (17)
2014 (2)
2013 (4)
2012 (2)

Posts By Category

.NET (4)
.NET Core (2)
ASP.NET MVC (4)
AWS (5)
AWS API Gateway (1)
Android (1)
Apache Camel (1)
Architecture (1)
Audio (1)
Azure (2)
Book review (3)
Business (1)
C# (3)
C++ (2)
CloudHSM (1)
Containers (4)
Corporate culture (1)
Database (3)
Database migration (1)
Desktop (1)
Docker (1)
DotNet (3)
DotNet Core (2)
ElasticSearch (1)
Entity Framework (3)
Git (3)
IIS (1)
JDBC (1)
Java (10)
Kibana (1)
Kubernetes (1)
Lambda (1)
Learning (1)
Life (7)
Linux (2)
Lucene (1)
Multi-threading (1)
Music (1)
OData (1)
Office (1)
PHP (1)
Photography (1)
PowerShell (2)
Programming (28)
Python (1)
Rants (5)
SQL (2)
SQL Server (1)
Security (3)
Software (1)
Software Engineering (1)
Software development (2)
Solr (1)
Sql Server (2)
Storage (1)
T-SQL (1)
TDD (1)
TSQL (5)
Tablet (1)
Technology (1)
Test Driven (1)
Testing (1)
Tomcat (1)
Unit Testing (1)
Unit Tests (1)
Utilities (3)
VC++ (1)
VMWare (1)
VSCode (1)
Visual Studio (2)
Wallpapers (1)
Web API (2)
Win32 (1)
Windows (9)
XML (2)

Posts By Tags

.NET(6) API Gateway(1) ASP.NET(4) AWS(3) Adults(1) Advertising(1) Android(1) Anti-forgery(1) Asynch(1) Authentication(2) Azure(2) Backup(1) Beliefs(1) BlockingQueue(1) Book review(2) Books(1) Busy(1) C#(4) C++(3) CLR(1) CORS(1) CSRF(1) CTE(1) Callbacks(1) Camel(1) Certificates(1) Checkbox(1) Client authentication(1) CloudHSM(1) Cmdlet(1) Company culture(1) Complexity(1) Consumer(1) Consumerism(1) Containers(3) Core(2) Custom(2) DPI(1) Data-time(1) Database(4) Debugging(1) Delegates(1) Developer(2) Dockers(2) DotNetCore(3) EF 1.0(1) Earphones(1) Elastic Search(2) ElasticSearch(1) Encrypted(1) Entity framework(1) Events(1) File copy(1) File history(1) Font(1) Git(2) HierarchyID(1) Hyper-V(1) IIS(1) Installing(1) Intelli J(1) JDBC(1) JSON(1) JUnit(1) JWT(1) Java(3) JavaScript(1) Kubernetes(1) Life(1) LinkedIn(1) Linux(2) Localization(1) Log4J(1) Log4J2(1) Logging(1) Lucene(1) MVC(4) Management(2) Migration history(1) Mirror(1) Mobile Apps(1) Modern Life(1) Money(1) Music(1) NGINX(1) NTFS(1) NUnit(2) OData(1) OPENXML(1) Objects(1) Office(1) OpenCover(1) Organization(1) PHP(1) Paths(1) PowerShell(2) Processes(1) Producer(1) Programming(2) Python(2) QAAC(1) Quality(1) REDIS(2) REST(1) Runtimes(1) S3-Select(1) SD card(1) SLF4J(1) SQL(2) SQL Code-first Migration(1) SSH(2) SSL(1) Sattelite assemblies(1) School(1) Secrets Manager(1) Self reliance(1) Service(1) Shell(1) Solr(1) Sony VAIO(1) Spirituality(1) Spring(1) Sql Express(1) System Image(1) TDD(1) TSQL(3) Table variables(1) Tables(1) Tablet(1) Ubuntu(1) Url rewrite(1) VMWare(1) VSCode(1) Validation(2) VeraCode(1) Wallpaper(1) Wallpapers(1) Web Development(4) Windows(2) Windows 10(2) Windows 2016(2) Windows 8.1(1) Work culture(1) XML(1) Yii(1) iTunes(1) open file handles(1) renew(1) security(1) static ip address(1) ulimit(1)