SSL Plugin
The SSL plugin provides a simple way to configure SSL and HTTP/2 for Javalin, just the same way you would configure Javalin itself!
How does it work?
The plugin provides a SslConfig
class that can be used to configure this plugin, which can be later registered with Javalin. This class can be configured using a lambda the same way you would configure Javalin itself.
- Java
- Kotlin
SSLPlugin plugin = new SSLPlugin(conf -> {
conf.pemFromPath("certs/cert.pem", "certs/key.pem");
});
Javalin.create(javalinConfig -> {
javalinConfig.plugins.register(plugin);
}).start();
val plugin = SSLPlugin { conf ->
conf.pemFromPath("/path/to/cert.pem", "/path/to/key.pem")
}
Javalin.create { javalinConfig ->
javalinConfig.plugins.register(plugin)
}.start()
By default two connectors are created, one for HTTP and one for HTTPS. The HTTP connector is NOT configured to redirect all requests to the HTTPS connector
(this can be achieved using the bundled plugin: javalinConfig.plugins.enableSslRedirects();
).
The default port for HTTP is 80 and for HTTPS is 443.
Getting Started
Add the dependency:
- Maven
- Gradle
<dependency>
<groupId>io.javalin.community.ssl</groupId>
<artifactId>ssl-plugin</artifactId>
<version>6.3.0</version>
</dependency>
Not familiar with Maven? Read our Maven tutorial.
implementation group: 'io.javalin.community.ssl', name: 'ssl-plugin', version: '6.3.0'
Not familiar with Gradle? Read our Gradle tutorial.
Configure the plugin:
- Java
- Kotlin
SSLPlugin plugin = new SSLPlugin(conf -> {
conf.pemFromPath("/path/to/cert.pem", "/path/to/key.pem");
// additional configuration options
});
val plugin = SSLPlugin { conf ->
conf.pemFromPath("/path/to/cert.pem", "/path/to/key.pem")
// additional configuration options
}
And register the plugin with Javalin:
- Java
- Kotlin
Javalin.create(javalinConfig -> {
javalinConfig.plugins.register(plugin);
}).start();
Javalin.create { javalinConfig ->
javalinConfig.plugins.register(plugin)
}.start()
As easy as that!
Configuration options
Connection options
Options such as the port and the host can be configured using the following variables (shown with their default values)
host = null; // Host to bind to, by default it will bind to all interfaces.
insecure = true; // Toggle the default http (insecure) connector.
secure = true; // Toggle the default https (secure) connector.
http2 = true; // HTTP/2 Support
insecurePort = 80; // Port to use on the http (insecure) connector.
securePort = 443; // Port to use on the SSL (secure) connector.
redirect = false; // Redirect all http requests to https.
sniHostCheck = true; // Enable SNI hostname verification.
tlsConfig = TLSConfig.INTERMEDIATE; // Set the TLS configuration.
The TLSConfig
enum provides a set of predefined configurations for the TLS protocol. The default configuration is TLSConfig.INTERMEDIATE
, which is based on the latest Mozilla’s guidelines. The following configurations are available:
TLSConfig.OLD
TLSConfig.INTERMEDIATE
TLSConfig.MODERN
You can also create your own custom configuration by using the TLSConfig
constructor.
Key loading options
The plugin provides a set of methods to load the certificate and key from different sources. The following methods are available:
PEM certificate and key:
pemFromPath("/path/to/cert.pem", "/path/to/key.pem"); // load from paths.
pemFromPath("/path/to/cert.pem", "/path/to/key.pem", "keyPassword"); // load from paths with the given key password.
pemFromClasspath("certName.pem", "keyName.pem"); // load from files in the classpath.
pemFromClasspath("certName.pem", "keyName.pem", "keyPassword"); // load from files in the classpath with the given key password.
pemFromInputStream(certInputStream, keyInputStream); // load from input streams.
pemFromInputStream(certInputStream, keyInputStream, "keyPassword"); // load from input streams with the given key password.
pemFromString(certString, keyString); // load from strings.
pemFromString(certString, keyString, "keyPassword"); // load from strings with the given key password.
PKCS#12/JKS keystores:
keystoreFromPath("/path/to/keystore.jks", "keystorePassword"); // load the keystore from the given path
keystoreFromClasspath("keyStoreName.p12", "keystorePassword"); // load the keystore from the given path in the classpath.
keystoreFromInputStream(keystoreInputStream, "keystorePassword"); // load the keystore from the given input stream.
Each of these methods are mutually exclusive, so only one of them can be used at a time.
Advanced configuration
Once the plugin is configured, there is a SSLPlugin#patch
method that can be used to patch the Jetty server. This method receives a Server
as a parameter and adds the configured connectors to it. This method can be used to apply the SSL configuration to a server that is not created by Javalin.
There are also a set of fields that can be used to further configure the plugin:
configConnectors(Consumer<ServerConnector>); // Set a Consumer to configure the connectors
securityProvider = null; // Use a custom security provider
withTrustConfig(Consumer<TrustConfig>); // Set the trust configuration, explained below. (by default all clients are trusted)
Trust Configuration
If you want to verify the client certificates (such as mTLS) you can set the trust configuration using the TrustConfig
class.
In contrast to the identity configuration, you can load multiple certificates from different sources.
By adding a TrustConfig
to the SSLPlugin
you will enable client certificate verification.
new SSLPlugin(ssl->{
// Load our identity data
ssl.pemFromPath("/path/to/cert.pem","/path/to/key.pem");
// Load the client/CA certificate(s)
ssl.withTrustConfig(trust->{
trust.certificateFromPath("/path/to/clientCert.pem");
trust.certificateFromClasspath("rootCA.pem");
});
});
// Certificate loading methods (PEM/DER/P7B)
certificateFromPath("path/to/certificate.pem"); // load a PEM/DER/P7B cert from the given path
certificateFromClasspath("certificateName.pem"); // load a PEM/DER/P7B cert from the given path in the classpath
certificateFromInputStream(inputStream); // load a PEM/DER/P7B cert from the given input stream
p7bCertificateFromString("p7b encoded certificate"); // load a P7B cert from the given string
pemFromString("pem encoded certificate"); // load a PEM cert from the given string
// Trust store loading methods (JKS/PKCS12)
trustStoreFromPath("path/to/truststore.jks", "password"); // load a trust store from the given path
trustStoreFromClasspath("truststore.jks", "password"); // load a trust store from the given path in the classpath
trustStoreFromInputStream(inputStream, "password"); // load a trust store from the given input stream
Hot reloading
Certificate reloading is supported, if you want to replace the certificate you can simply call SSLPlugin.reload()
with the new configuration.
// Create the plugin outside the Javalin config to hold a reference to reload it
SSLPlugin sslPlugin = new SSLPlugin(ssl->{
ssl.pemFromPath("/path/to/cert.pem","/path/to/key.pem");
ssl.insecurePort = 8080; // any other config you want to change
});
Javalin.create(config->{
... // your Javalin config here
config.plugins.register(sslPlugin);
});
// later on, when you want to replace the certificate
sslPlugin.reload(ssl->{
// any options other than loading certificates/keys will be ignored.
ssl.pemFromPath("/path/to/new/cert.pem","/path/to/new/key.pem");
// you can also reload the trust configuration
ssl.withTrustConfig(trust->{
trust.certificateFromPath("/path/to/new/cert.pem");
});
});
Good to know
-
This plugin can be used to enable HTTP/2 without the need to use a certificate. To do so, just set the
secure
option tofalse
and thehttp2
option totrue
. -
HTTP/3 is not supported yet, but it is planned to be added in the future. The IETF is still working on the final specification, so it is not prudent to implement it yet.
-
Jetty 11 ships with SNI verification enabled by default, if hostname spoofing is a not concern, you can disable it by setting the
sniHostCheck
option tofalse
. This option is enabled by default for security reasons, but it can be disabled if you are using a reverse proxy that handles the hostname verification. Jetty might respond with anHTTP ERROR 400 Invalid SNI
if the hostname verification fails. -
mTLS (Mutual TLS) is supported, just add a
TrustConfig
to theSSLPlugin
to enable client certificate verification. See the Advanced Configuration section for more information.