Glassfish 3.1.2 - after creating cluster & deploying app j_security_check loop

938 views Asked by At

I've finally got my app deployed to a 2 instance single node test cluster fronted by apache/mod_jk load balancing.

In a non-clustered environment I've been using container security with JDBCRealm for ages and it works reliably.

In the cluster environment, I get the login page in the browser, type a valid username and password, click the submit button and j_security_check sets the location page in the response header as the login page, not the welcome-file. It fowards to the login page we were just on.

I've enabled the MySQL general query log and can see that password & group name are being read from the right table for the right user.

I tried setting javax.enterprise.system.core.security.level=FINEST but there's still no output in the server log.

With the same app deployed to the local server rather than the cluster I can access localhost:8080/ and login ok. If I just type "localhost" and go through the load balancer it won't work.

I know that j_security_check can forward to the page that triggered the authentication (which is presumably what's happening here), but when does it forward to the welcome-file, when there is no "page that triggered the authentication"? Edit: I see now, it always 302 redirects to the referer, which is the context-root in this case. The container must have some rules which determine which page actually gets shown. In my cluster example it is not the welcome-file from web.xml.

I also setup my auth realm in the cluster config:

asadmin> create-auth-realm --target c1 --classname com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm --property jaas-context=jdbcRealm:datasource-jndi=jdbc/sportquest:user-table=users:user-name-column=username:password-column=password:group-table=users:group-name-column=groupname:digest-algorithm=SHA-256:encoding=Base64

The only difference I can think of between the two environments is that in the cluster setup I have a mod_rewrite rule which fowards from http -> https (httpd.conf):

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# This redirects from thingy.com to www.thingy.com
#
RewriteCond %{HTTP_HOST} !^thingy\.com$ [NC]  
RewriteRule ^(.*)$ %{HTTPS}://thingy.com/$1 [R=301,L]

Edit: added below chrome dev tools network trace

The working scenario deployed as /MyApp:

GET http://localhost:8080/MyApp - 301 Moved Permanently (from cache)
GET http://localhost:8080/MyApp/ - 200 Ok
 ... login page loads ...
POST http://localhost:8080/MyApp/j_security_check - 302 Moved Temporarily
  the form data contains user/pass as expected & response header Location:
  http://localhost:8080/MyApp/
GET http://localhost:8080/MyApp/ - 200 Ok
 ... welcome-file page loads ...

The not working scenario (cluster) deployed as root / :

GET http://localhost/ - 301 Moved Permanently (from cache)
GET https://localhost/ - 200 Ok
 ... login page loads ...
POST https://localhost/j_security_check - 302 Moved Temporarily
  the form data contains user/pass as expected & response header Location:
  https://localhost/
GET https://localhost/ - 200 Ok
 ... the login page loads ...

If I type in invalid login credentials then in both cases I successfully redirect to the form-error-page.

Anyone got any suggestions? I'm just not seeing it. Thanks.

p.s. I did try a browser cache clean, no help!

Update: The problem is that in the clustered/mod_jk environment the postback from j_security_check has a Set-Cookie with a new sessionid, so the next request comes in on a different session. It seems that this is something to do with sticky sessions, however I still don't know how to fix it. I've tried setting the loadbalancer sticky_sessions to true and false but neither helps.

jvmRoute is set for both instances to the workers.

1

There are 1 answers

0
Jordan Denison On

Why don't you just use mod_proxy & mod_proxy_balancer instead? That way you can set the reverse cookie path for the different context roots. Let me know if you need some configuration examples (on the iPhone atm)