I have a Grails app using Spring Security Core running on an AWS machine behind a load balancer.
The load balancer decrypts the ssl connections and forwards to port 8080 of our instance adding appropriate X-Forwarded-Proto headers.
I would like any direct access to a secured page to redirect to the login page using https.
For example a request https://myapp.com/private/page should redirect to https://myapp.com/login/auth
I put this in my config.groovy:
grails.plugin.springsecurity.secureChannel.definition = [
'/login/**': 'REQUIRES_SECURE_CHANNEL'
]
but this causes a redirect loop (HTTP code 302) to the http login page (http://myapp.com/login/auth)
Then I tried just with:
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.auth.forceHttps = true
but this causes a redirect (HTTP code 302) to the http login page (http://myapp.com/login/auth)
No luck lurking at similar posts, any idea?
I also am hosting my Grails app with Spring Security Core 2.0-RC4 on AWS with https and a load balancer, and thanks to spock99 (above) and Ravi L of AWS, I got it working.
I did the following in config.groovy:
// Required because user auth uses absolute redirects
grails.serverURL = "http://example.com"
grails.plugin.springsecurity.secureChannel.definition = [
'/assets/**': 'ANY_CHANNEL',// make js, css, images available to logged out pages
'/**': 'REQUIRES_SECURE_CHANNEL',
]
// overriding values in DefaultSecurityConfig.groovy from the SpringSecurityCore 2.0-RC4
grails.plugin.springsecurity.secureChannel.useHeaderCheckChannelSecurity = true
grails.plugin.springsecurity.portMapper.httpPort = 80
grails.plugin.springsecurity.portMapper.httpsPort = 443
NOTE: The following were not needed in Spring Security Core 2.0-RC4 - they are already in DefaultSecurityConfig.groovy
secureHeaderName = 'X-Forwarded-Proto'
secureHeaderValue = 'http'
insecureHeaderName = 'X-Forwarded-Proto'
insecureHeaderValue = 'https'
I was getting false 'Unhealthy' readings because hitting '/' returns a 302 redirect to /login/auth, so I added a health() method to HomeController (which I mapped to '/health') for AWS to hit:
class HomeController {
@Secured('IS_AUTHENTICATED_FULLY')
def index() { }
@Secured('permitAll')
def health() { render '' }
}
Key for me was that session cookies were not being handled properly with multiple instance running on the Load Balancer (I did not discover this until setting the minimum instance to 2), so in order for users to be able to log in and stay logged in, I did the following on AWS:
1. At Services / Elastic Beanstalk / Configuration / Load Balancing
a. set Application health check URL: /health
b. left Session Stickiness: unchecked
2. At Services / EC2 / Load Balancers / Description / Port Configuration:
For both port 80 (HTTP) and 443 (HTTPS)
1. Edit and select 'Enable Application Generated Cookie Stickiness'
2. Cookie Name: JSESSIONID
I just went through the same scenario. Got stuck on the https, then the redirects, and now all is well. Use these Config.groovy settings:
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'
Note for those not using springsecurity 2.0, it is 'plugins' and not 'plugin' without the 's'.
My beanstalk load balancer settings look like this (I have an SSL cert installed, I didn't show it):
In the EC2 load balancer settings make sure your listeners are set right:
And finally in the EC2 security groups make sure the EB accepts requests on ports 80 and 443 from the ELB:
Note that nowhere in my setup of anything do I ever reference ports 8080 or 8443, even though that is what I use on my localhost for testing. Somebody reading this may think about trying to use those ports to fix the issues. My setup didn't require that.
I faced similar issue in similar environment where the front end was on https and behind the firewall grails server was on http. When session was timed out, ajax and angular $http used to get a redirect message to http://myclient.com/myWar/login/auth. This redirect request used to cause access denied in browser because original url was https and mixed content was disabled. I used to get SCRIPT7002: XMLHttpRequest: Network Error 0x80700013, Could not complete the operation due to error 80700013.” This error occurred only in production and not in test environment.
Fix is simple, simply add the following to the configuration file. grails.serverURL = "https://mywebsitespublicaddress.com/myWar"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With