Search code examples
grailsrun-app

Grails 3 force https by default


I have a Grails 3 application in works. I want to force the run-app to use https by default. There are several posts dating back to a year or so ago, Most recent post, showing possible methods to force https by default. i.e using an alias, or using the run-app -https command.

I am bringing this issue back up to the table to see if anyone has managed to make https run by default without using explicit methods in the previous posts. Surely, for those that always want to run the app with https enabled by default, whether it be through the cli or IDE, this is a desired feature. Could we possibly pass it as an argument somewhere before the run-app command, so that we do not have to explicitly state it in different environments of use?

For ex:

I have tried editing the build file to pass a jvm argument, with no luck.

bootRun {
    jvmArgs = "-D-https"
}

Solution

  • To make this work, I shifted gears towards a different approach. This question can be solved by following the instructions in this post: Embedded Tomcat enable SSL

    Unlike the -https option, using this approach, we need to create our own keystore file and store it somewhere. We could also use the keystore generated by grails, which is by default located in the build directory. However, we would have to move its location to a more permanent place, as the build directory can be cleaned. Note: you can get the password and data for the keystore by checking the systemProperties passed in bootRun.

    bootRun {
        print systemProperties
    }
    

    My output was as follows:

    endpoints.shutdown.enabled:true, env:development, full.stacktrace:false, grails.env:development, grails.full.stacktrace:false, info.app.grailsVersion:3.1.2, info.app.name:coolio, info.app.version:0.1, interactive.mode.enabled:true, run.active:true, server.port:8443, server.ssl.key-password:123456, server.ssl.key-store:./build/ssl/keystore, server.ssl.key-store-password:123456, verbose:false
    

    My configuration did not have the exact attributes as shown by the authors, and rather a mix of only needed parts:

    private static Connector getSslConnector() {
        def dir = System.getProperty("user.dir")
        Connector connector = new Connector();
        connector.setPort(8443);
        connector.setSecure(true);
        connector.setScheme("https");
        connector.setAttribute("keystorePass", "coolio");
        connector.setAttribute("keystoreFile", dir + "/.keystore");
        connector.setAttribute("clientAuth", "false");
        connector.setAttribute("protocol", "HTTP/1.1");
        connector.setAttribute("sslProtocol", "TLS");
        connector.setAttribute("maxThreads", "200");
        connector.setAttribute("protocol", "org.apache.coyote.http11.Http11NioProtocol");
        connector.setAttribute("SSLEnabled", true);
        return connector;
    }
    

    Note, the original post set the protocol attribute to:

    connector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol");
    

    And I set the attribute equal to:

    connector.setAttribute("protocol", "org.apache.coyote.http11.Http11NioProtocol");
    

    Other than that, attach the connector to the tomcat service, as shown in the previous article, and all should work as intended. You can now do run-app, with both http and https being present.