10

This issue is driving me insane, so maybe someone could help me understand what the issue is. I have a tomcat web application being fronted by HAProxy. HAProxy is also doing SSL offloading, and is configured to use sticky sessions. I am using Tomcat's session replication feature which seems to be working just fine. The sessions appear on both appservers.

For some reason, Tomcat is generating a new JSESSIONID for every single web request, and then copying the contents of the old session into the new session. That is to say, my session contents are still there within the new session, but a new ID is generated and sent back to the client. But it only does this for my web application. It does not do this for the /manager application.

I have tried every trick in the book, such as setting this in my context.xml:

<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false" />

And setting these attributes on my Context element:

<Context path="/myapp" reloadable="false" override="true" useNaming="false" allowLinking="true" useHttpOnly="false" sessionCookiePath="/" sessionCookiePathUsesTrailingSlash="false">

And still, the result is the same. Tomcat generates a new session id with every request and copies the contents of the old session into the new id.

I would suspect it had something to do with HAProxy, except that the /manager application is also behind HAProxy and it does not exhibit this behavior.

Why is Tomcat doing this, and what can I do to prevent it?

Nobody
  • 690
  • 2
  • 9
  • 18

3 Answers3

9

Turns out that it was cause by Spring Security. We are using Spring Security 3.1x, and by default it stores the authenticated credentials in the user's session. And to counter session fixation attacks, it automatically copies the contents of the user's session to a new session id and invalidates the old session.

The fix was to add the following to the http element in the security configuration, since we don't need to use the session in our application:

create-session="stateless"

Hopefully this helps someone else down the line.

Nobody
  • 690
  • 2
  • 9
  • 18
  • 1
    At least from Spring Security 3.2.5, there is also the session fixation behaviour activated by default. Configuring `HttpSecurity http` in a custom `WebSecurityConfigurerAdapter` with a `http.sessionManagement().sessionFixation().none();` can solve the problem. Double check on the implications, then (no more automatic session fixation). – Eric Platon Jan 15 '15 at 01:21
4

I got the same problem with new id session when I refresh page On tomcat7 server, I only add into the context.xml this code :

<Valve className="org.apache.catalina.authenticator.BasicAuthenticator" changeSessionIdOnAuthentication="false" />

<Context path="/myapp" reloadable="false" override="true" useNaming="false" allowLinking="true" useHttpOnly="false" sessionCookiePath="/" sessionCookiePathUsesTrailingSlash="false">

This work fine for me.

Patrikoko
  • 478
  • 5
  • 5
1

Not sure exactly what your problem is, but there are two things I would check. First, did you specify the jvmRoute in tomcat?

Tomcat server.xml

<Engine name="Catalina" defaultHost="localhost" jvmRoute="machine1">

Haproxy.cfg (references jvmRoute)

server machine1 SERVER_IP cookie machine1 check 

Tomcat appends the name of the server to the cookie, so not setting that can cause issues.

The other thing to check is to make sure that you added this line to your web.xml in the web-app section

<distributable />
jcern
  • 7,798
  • 4
  • 39
  • 47
  • Thanks for the suggestion, I have tried that but to no avail. Also, I don't believe HAProxy uses jvmRoute. I have used that in the past when fronting with apache, but HAProxy prepends the configured server name to the cookie itself before sending to the client. – Nobody Jan 22 '13 at 19:59
  • Forgot to add, I already have my webapp marked as distributable. As I said, my session replication is working fine. – Nobody Jan 22 '13 at 19:59
  • @Unsavory sorry, I couldn't be more help but I figured it was worth a shot. We use the same configuration, and had a similar issue when we set things up. In our case, it was because HAProxy was mangling the cookie and it was getting bounced between servers periodically. Setting the `jvmRoute` on Tomcat and the `cookie`, `appsession`, and `server` accordingly fixed it for us. – jcern Jan 22 '13 at 20:16
  • I appreciate the effort, however this does not seem to be the issue in our case. Also, the load balancing with sticky sessions is working properly. We are never getting bounced between servers. Like I said in my question, everything works correctly for the manager app, so it is something about the configuration for my webapp, but have been unable to figure out what that is. – Nobody Jan 22 '13 at 21:12