I put together a few pieces of information from around the Internet today to allow the “grails run-app” command to run with a confidential transport guarantee.
“grails run-app-https” could be a viable option under some circumstances. Unfortunately it falls short of the happy-path support in most(?) Grails-aware IDEs. run-app-https also does not behave in the way that my deployed application does; specifically, it does not redirect traffic from the http port to the https port when confidential transport is requested.
Setting up a keystore
Instructions for generating a certificate that you can use for SSL in Jetty can be found at http://docs.codehaus.org/display/JETTY/How+to+configure+SSL. Similar instructions for Tomcat can be found at http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html.
In short, keytool – included in a JDK – can generate your certificate with:
%JAVA_HOME%\bin\keytool -genkey -alias jetty -keyalg RSA
(Windows)
Note that the default certificate is valid for 3 months. If you would like to generate a certificate that lasts longer, add -validity to the command. If you decide to use a self-signed certificate, then when prompted to enter your first and last name during the certificate creation process, instead enter the hostname of your server. This is the name that browsers will compare to the website’s URL. If the name on the cert and the URL do not match browsers will display a security warning.
The certificate is created in your home directory, and as long as you are running the server (like through “grails run-app” at the command line, or through an IDE) that should be fine. If you are running the server as a service/daemon then you might need to copy it elsewhere or otherwise consider its applicability to the server environment.
Configuring Jetty
You can set up a jetty-env.xml file within Grails, which works fine for setting up datasources through JNDI, but it is meant to configure the Jetty WebAppContext rather than the Jetty Server. Grails does not provide a direct means for configuring the Jetty Server, but there is an indirect method using an event listener. You can find information about doing this in 4.3 Hooking into Events in the 1.0.x Grails reference documentation.
The Jetty API provides additional background for the actions contained in the following script. Adjust the password information as appropriate based on what you provided when you created the certificate.
eventConfigureJetty = { server ->
println '==In USER_HOME/.grails/scripts/_Events.groovy - eventConfigureJetty...'
c = server.getConnectors()
assert c.length == 1
c[0].confidentialPort = 8443
ssl = new org.mortbay.jetty.security.SslSocketConnector()
ssl.port = 8443
ssl.maxIdleTime = 200000
keystore = "${System.getProperty('user.home')}/.keystore"
println "Using keystore ${keystore}"
ssl.keystore = keystore
ssl.password = 'password'
ssl.keyPassword = 'password'
server.addConnector(ssl)
println '==eventConfigureJetty complete.'
}
This script should be located in your USER_HOME/.grails/scripts directory and named _Events.groovy. It is invoked during startup, so you should see the printlns once when Jetty is started. System.getProperty(‘user.home’) should resolve to your user ID, and cause the “.keystore” file in your home directory to be used. You can obviously adapt the script to your platform/keystore directory needs.