Friday, November 30, 2018

Configure Spring Boot to use HTTPS

If you're writing a Spring Boot application and want to and enable SSL (https) on the embedded Tomcat, here a few short steps you will need to take. (This has been tested with Spring Boot 2.0.5.RELEASE.)
  1. Get an SSL certificate.
    Fortunately, Java has a tool for doing this called keytool.
    keytool -genkey -alias tomcat \
     -storetype PKCS12 -keyalg RSA -keysize 2048 \
     -keystore keystore.p12 -validity 365
    What does each flag mean? Let's break it down.
    • -genkeypair Generates a key pair (a public key and associated private key), wraps the public key into an X.509 v3 self-signed certificate, which is stored as a single-element certificate chain.
    • -alias tomcat This is how we will refer to the key pair in the keystore. Here we are going to call it 'tomcat'.
    • -storetype PKCS12 This is the archive file format, used to bundle the private key with its certificate. Here we are using PKCS 12.
    • -keyalg RSA Specifies the algorithm to be used to generate the key pair. Here we are using RSA .
    • -keysize 2048 The size (in bytes) of each key to be generated. Here we specify 2K.
    • -keystore keystore.p12. The name of the keystore file to generate. Here we are calling it 'keystore.p12'.
    • -validity 365 How long the certificate is valid. Here we specify 1 year.
    Since we did not use the -dname flag, keytool will interactively ask you questions for the certificate's distinguished name: 
    Since this is for development, you may simply press 'Enter' at each prompt. (Be sure to answer 'yes' at the end though.) 
  2. Enable HTTPS in Spring Boot
    This part is pretty simple. Open your Spring Boot and configure it like this:
    server.port: 8443
    server.ssl.key-store: keystore.p12
    server.ssl.key-store-password: mypassword
    server.ssl.keyStoreType: PKCS12
    server.ssl.keyAlias: tomcat
    Restart your app and test the URL at https://localhost:8443. Since we self-signed our certificate, you will see an ugly warning like this:

    Depending on your browser, navigate to the 'Advanced' option and proceed to your application.
  3. Redirect HTTP to HTTPS
    Wouldn't it be nice if the old port redirected to this new secure port? Yes, it would.
    We will need to add a second Tomcat connector. However, we cannot do it in the So we'll have to do it programmatically, by creating our own TomcatServletWebServerFactory and overriding the postProcessContext method. 
    Add this code to one of your @Configuration beans (except for WebSecurityConfigurerAdapter, if you're using one):
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory serverFactory = new TomcatServletWebServerFactory() {
            protected void postProcessContext(Context context) {
                SecurityCollection collection = new SecurityCollection();
                SecurityConstraint securityConstraint = new SecurityConstraint();
        return serverFactory;
    private Connector redirectConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        return connector;
    Restart your app and test the URL at http://localhost:8080. Yay! It redirects to https.