5

I have a grails application with the spring-security-core plugin installed. Everything works fine locally. I deployed to a staging server and everything worked fine. I deployed to our production server which is a mirror of our staging server. I can get to unprotected pages just fine. But when Spring Security kicks in and tries to do it's redirects it is redirecting to localhost instead of the grails.serverURL.

I'm going to turn up logging as high as possible and redeploy to see if I can make heads or tails of anything. I'll post my finding here. If anyone has experienced this before and knows what might be happening, please let me know. Also, if there are any configuration files that need to be seen I can provide those as well. Thanks.

Update I added the following to the bottom Config.groovy

grails.plugins.springsecurity.useSecurityEventListener = true

grails.plugins.springsecurity.onAuthorizationEvent = { e, appCtx ->
   println "here"
   println e
}

Locally, that closure gets hit 2 times when I try and access a protected page. Once for the initial url. Second time for the auth url. Deployed this to our production server and I get nothing.

Gregg
  • 34,973
  • 19
  • 109
  • 214

4 Answers4

8

The redirects are done in org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint.commence() method, so you could set a breakpoint there if you're able to borrow one of the prod servers for debugging.

It builds the redirect URL based on the login form uri (e.g. /login/auth) but it uses request.getServerName() so it should be the same as the original request. Note that grails.serverURL has no impact here since it builds the URL using the requested server name, port, context, etc.

It might be affected by putting Apache or a load balancer in front of your servlet container, although I've done both and it's worked fine.

Have you done any bean customization in resources.groovy that might affect this?

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
Burt Beckwith
  • 75,342
  • 5
  • 143
  • 156
  • Thanks Burt. No, our resources.groovy is actually empty. We do have apache sitting in front with mod_proxy. The biggest confusion point for me is why it would be working on one server, but not the other, when both are configuration exactly the same way except for the domain that is mapped to it via DNS. – Gregg Oct 07 '10 at 20:14
  • I marked this answer as correct for my problem in that request.getServerName() is indeed returning localhost, which is incorrect. So I just need to track down why that is happening. – Gregg Oct 07 '10 at 20:38
  • In my case it was wrongly configured reverse proxy in nginx it was missing: proxy_set_header Host $host; – JJ Roman Apr 30 '20 at 20:33
  • in my case tomcat+apache in front+cloudflare. I had add "ProxyPreserveHost On". cloudflare was messing up. – Arjang Apr 27 '23 at 14:23
6

If your application server is behind a web server, this problem is likely caused by your web server configuration. I had this same problem and corrected it by using the following entry in my httpd.conf or apache2.conf. Here it is...

...boilerplate configuration here...

################################
# Begin yourdomain.com...      #
################################

ProxyRequests Off
ProxyPreserveHost On

<Proxy>
    Order deny,allow
    Allow from all
</Proxy>

ProxyPass / http://localhost:28080/
ProxyPassReverse / http://localhost:28080/

<Location>
    Order allow,deny
    Allow from all
</Location>

################################
# ... end yourdomain.com       #
################################
HybrisHelp
  • 5,518
  • 2
  • 27
  • 65
ed.singleton
  • 61
  • 1
  • 1
2

Assuming you have a webserver (apache, nginx, etc) as a proxy in front of Tomcat (and you are using Tomcat)...

In a setup where you allow both http and https, add a separate Connector element to tomcat's conf/server.xml file:

<Connector port="8081" protocol="HTTP/1.1" 
           connectionTimeout="20000" 
           redirectPort="8443"  URIEncoding="UTF-8"
           scheme="https" secure="true" proxyName="somehostname.domain" proxyPort="443" />

If only https is allowed, you can add the scheme, secure, proxyName and proxyPort attributes to the existing Connector element.

In apache config, make the *:443 virtual host proxy to the Connector with the extra attributes. The plain http *:80 can connect to the original Connector.

For more information: http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Proxy_Support http://tomcat.apache.org/tomcat-7.0-doc/proxy-howto.html

Lari Hotari
  • 5,190
  • 1
  • 36
  • 43
2

I know this is an old question, but I would like to add my findings to help other users that might encounter this problem.

In addition to Burt's answer (I'm assuming that you are using tomcat), I found out that the returned value of request.getServerName() can also be set via server.xml

i.e in tomcat 8 https://tomcat.apache.org/tomcat-8.0-doc/config/http.html

having this line in server.xml

<Connector protocol="HTTP/1.1"
           port="8080" ...
proxyName="localhost"/>

would return "localhost" when getServername is invoked.

bertanasco
  • 101
  • 5