IMLC.ME
Search…
en-US
Powered By GitBook
How to enable mutual authentication in Jetty server
Enable mutual authentication/mTLS in Jetty server, Java mTLS, Jetty client authentication
mutual authentication is a common way to authentication your client or integrate with upstream/downstream services. This post will demostrate how to enable mutual authentication, or so-call mTLS in SSL, in Jetty server.
The overall source code is stored at https://github.com/lawrenceching/jetty-mtls-example.

Prepare Certificates

Change the password "changeit" in below commands if you generate a real certificate in production.
Run below commans to generate server and client certificates. It's notable that when terminal prompts your to input your first name and last name, input your domain name or ip address. It's mandatory that your hostname match your certificate.
I assume that you generate certs in src/main/resources where we normally do.
1
# Generate server keystore
2
keytool -genkey -alias server -keyalg RSA -keypass changeit -storepass changeit -keystore server.jks
3
4
# Export server certificate from server keystore and import it into truststore.
5
# Client need it to validate server certificate in mTLS.
6
keytool -export -alias server -storepass changeit -file server.cer -keystore server.jks
7
keytool -import -file ./server.cer -alias server -keystore client_truststore.jks
8
9
# ---
10
11
# Generate client keystore
12
keytool -genkey -alias client -keyalg RSA -keypass changeit -storepass changeit -keystore client.jks
13
14
# Export client certificate and import in into truststore.
15
# Server need it to validate client certificate in mTLS.
16
keytool -export -alias client -storepass changeit -file client.cer -keystore client.jks
17
keytool -import -file ./client.cer -alias client -keystore server_truststore.jks
18
19
# You you can convert them to PKCS12 or PEM format
20
keytool -importkeystore -srckeystore client.jks -destkeystore client.p12 -srcalias client -srcstoretype jks -deststoretype pkcs12
21
openssl pkcs12 -in client.p12 -nokeys -out client.crt
22
openssl pkcs12 -in client.p12 -nocerts -nodes -out client.key
23
24
Copied!

Configurate Client Certificate in Jetty Server

The key to Jetty is to configurate the SslContextFactory. Things are pretty straightforward. You set the KeyStore and KeyStore password, and then set the TrustStore and TrustStore password. You need to call setNeedClientAuth(true) to enable mTLS.
1
// https://github.com/lawrenceching/jetty-mtls-example/blob/master/src/main/java/me/imlc/JettyMtlsServer.java#L25-L32
2
SslContextFactory.Server sslContextFactory = new SslContextFactory.Server();
3
sslContextFactory.setKeyStorePath(this.getClass().getResource(
4
"/server.jks").toExternalForm());
5
sslContextFactory.setKeyStorePassword("changeit");
6
7
sslContextFactory.setTrustStorePath(this.getClass().getResource("/server_truststore.jks").toExternalForm());
8
sslContextFactory.setTrustStorePassword("changeit");
9
sslContextFactory.setNeedClientAuth(true);
Copied!

Verification

CURL

We usually use curl to be a test client. However curl doesn't know .jks file. So we need some convertion.
1
# Convert KeyStore to pkcs12 format
2
keytool -importkeystore -srckeystore client.jks -destkeystore client.p12 -srcalias client -srcstoretype jks -deststoretype pkcs12
3
4
# Convert private key and certificate to .key and .crt in PEM format
5
openssl pkcs12 -in client.p12 -nokeys -out client.crt
6
openssl pkcs12 -in client.p12 -nocerts -nodes -out client.key
7
8
# curl it!
9
curl -v -k https://localhost:8443 \
10
--cert ./client.crt \
11
--key ./client.key
12
13
# Or
14
curl -v -k --cert-type=P12 --cert ./client.p12 \
15
https://localhost:8443
Copied!

Java HTTP Client

Or you may want to call mTLS server in Java client. Here is an example using Jetty http client. You can find similar configuration in OkHttp or Apacha Http Client.
1
https://github.com/lawrenceching/jetty-mtls-example/blob/master/src/test/java/me/imlc/JettyMtlsServerTest.java#L26-L46
2
@Test
3
public void canAuthenticateClient() throws Exception {
4
SslContextFactory sslContextFactory = new SslContextFactory.Client();
5
sslContextFactory.setKeyStorePath(this.getClass().getResource(
6
"/client.jks").toExternalForm());
7
sslContextFactory.setKeyStorePassword("changeit");
8
9
sslContextFactory.setTrustAll(true);
10
11
sslContextFactory.setTrustStorePath(this.getClass().getResource(
12
"/client_truststore.jks").toExternalForm());
13
sslContextFactory.setTrustStorePassword("changeit");
14
15
HttpClient httpClient = new HttpClient(sslContextFactory);
16
17
18
httpClient.start();
19
20
ContentResponse response = httpClient.newRequest("https://localhost:8443")
21
.send();
22
23
assertThat(200, equalTo(response.getStatus()));
24
assertThat("Hello, world", equalTo(response.getContentAsString()));
25
26
httpClient.stop();
27
}
Copied!
Last modified 1yr ago