Using SSL and Tomcat with xsbt-web-plugin

November 12, 2016

In getting started with xsbt-web-plugin, we walked through building a basic Scala Web application using sbt and xsbt-web-plugin.

Let's see how we can enable SSL to serve our project over HTTPS directly from sbt.

Creating a certificate

We'll create a basic self-signed certificate, KeyStore, and TrustStore by following the steps in this tutorial. By convention, passwords throughout will be the not-so-secure phrase changeit.

$ keytool -genkey -alias server-alias -keyalg RSA -keypass changeit \
          -storepass changeit -keystore keystore.jks
What is your first and last name?
  [Unknown]:
What is the name of your organizational unit?
  [Unknown]:
What is the name of your organization?
  [Unknown]:
What is the name of your City or Locality?
  [Unknown]:
What is the name of your State or Province?
  [Unknown]:
What is the two-letter country code for this unit?
  [Unknown]:
Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
  [no]:  yes
$ keytool -export -alias server-alias -storepass changeit \
          -file server.cer -keystore keystore.jks
Certificate stored in file <server.cer>
$ keytool -import -v -trustcacerts -alias server-alias \
          -file server.cer -keystore cacerts.jks -keypass changeit \
          -storepass changeit
Trust this certificate? [no]:  yes
Certificate was added to keystore
[Storing cacerts.jks]

Configuring xsbt-web-plugin

We'll be using Tomcat, so let's enable it:

enablePlugins(TomcatPlugin)

The Tomcat plugin uses webapp-runner, which allows us to enable SSL via --enable-ssl:

containerArgs := Seq(
  "--enable-ssl"
)

We'll use a recent version of webapp-runner to make sure it has this feature:

containerLibs in Tomcat := Seq(
  "com.github.jsimone" % "webapp-runner" % "8.5.5.0" intransitive()
)

To enable SSL, we need to point the JVM toward our KeyStore, TrustStore, and proivde the corresponding passwords:

javaOptions in Tomcat ++= Seq(
  "-Djavax.net.ssl.keyStore=/home/james/code/xwp-template/keystore.jks",
  "-Djavax.net.ssl.keyStorePassword=changeit",
  "-Djavax.net.ssl.trustStore=/home/james/code/xwp-template/cacerts.jks",
  "-Djavax.net.ssl.trustStorePassword=changeit"
)

By default, xsbt-web-plugin binds our project to port 8080, but let's use something more HTTPS-ish instead:

containerPort := 8443

Now we can run our project from sbt with tomcat:start, and view it at https://localhost:8443/. Since we used a self-signed certificate, we may need to reassure our Web browser that it's safe to proceed.