0

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.

Oversteer
  • 1,778
  • 1
  • 22
  • 38

1 Answers1

0

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)

Jordan Denison
  • 2,649
  • 14
  • 14