This snippet configures proper detection of the http/https channel security by a Grails 2.3.2 application using the (latest) Spring Security 2.0-RC2 grails plugin. This configuration resides-in grails-app/conf/Config.groovy.
// belongs in 'production' environment block or guarded by, e.g. a System.property-check.
// [heroku] proxy support -- allow SSL to be terminated at the load balancer / proxy
// look for X-FORWARDED-PROTO (case-sensitive)
// https://discussion.heroku.com/t/grails-spring-security-core-securechannel-definition-causes-redirect-loop/219/2
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
grails.plugin.springsecurity.secureChannel.secureHeaderName = 'X-FORWARDED-PROTO'
grails.plugin.springsecurity.secureChannel.secureHeaderValue = 'http'
grails.plugin.springsecurity.secureChannel.insecureHeaderName = 'X-FORWARDED-PROTO'
grails.plugin.springsecurity.secureChannel.insecureHeaderValue = 'https'
Heroku, as with other hosting providers, terminates SSL connections at their load-balancer and acts a reverse-proxy back to the customer's dyno instances. The connection between the load-balancer and the dyno is over http, not https. Heroku adds the standard X-FORWARDED-PROTO header whose value indicates the protocol the client's request arrived-on.
Useful notes and resources:
- Heroku provides free SSL support for all apps hosted at *.herokuapp.com; only 'custom domains' such as www.mydomain.com require the SSL add-on
- Grails Spring Security Channel Security Docs
- The channelSecurity configuration should be included wherever you deploy to heroku, typically in the 'production' environment blocks in Config.groovy
- the Heroku X-FORWARDED-PROTO is:
- in-all CAPS
- inspected by case-sensitive Spring code -- so don't 'fix' the casing to something less-shouty like X-Forwarded-Proto ('standard', Amazon EC2)
- these properties live in the grails.plugin.* space along with other Grails 2.x plugins. You may find almost-identical configurations on the net documenting the 1.2.x version of this plugin with properties in grails.plugins.* (note plugins is plural). A 'plugins' config will not work, though you will get some nice ERROR logging, if you're in to reading logs and such.