Fork me on GitHub

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.

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:

<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:

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:

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

Like Javalin?
Star us 😊

×