Tomcat – Apache httpd mod_rewrite with Tomcat resulting in lost JSESSIONID

httpdmod-jkmod-rewritesessiontomcat

I'm working on a Java web application, for which I recently implemented an authentication module that relies on the JSESSIONID cookie to identify users. I was testing on a local tomcat from eclipse and everything worked fine… Until I deployed the application on our VPS (Centos) with a bit of a more advanced setup structure:

  • Apache HTTP Server

  • several virtual hosts

  • said webapp is mounted in a virtual host with mod_jk. It's currently accessed over 'sub.hostname.com/WEBAPP_NAME/home', but should be available with 'sub.hostname.com/home'.

The above setup wasn't such a big issue before the authentication update (btw, access was handled by tomcat's security options before). The old VirtualHost looked like this and worked fine:

<VirtualHost *:80>
    ServerName sub.hostname.com
    RewriteEngine on
    RewriteRule ^/(.+)$ /WEBAPP_NAME/$1 [L,PT]
    RewriteRule ^/$ /WEBAPP_NAME/home [L,PT]
    JkMount /* worker
</VirtualHost>

The Issue: After deployment, authentication would not work because the JSESSIONID cookie was not written. I removed the RewriteRules and accessed the application over 'sub.hostname.com/WEBAPP_NAME/home', where everything worked fine again and I received a cookie. From these observations, I guess that the issue is because of the URL being rewritten and the Servlet not writing the cookie to the correct path (?) If that's the case, should I try to write the cookie to some other path from within the application?

Are there any specific settings to look out for in apache or tomcat that can handle this? Or did I initially choose a wrong setup architecture?

Best Answer

I did some more research after reading CĂ©dricC's suggestions and found this: Configuring Apache, Tomcat, mod_jk and mod_rewrite to serve up tomcat from top-level

I followed the instructions by Kevin Loney to modify the http headers directly from Apache by using the mod_headers module.

In the end I just had to add the following line to my VirtualHost configuration, which changes all cookie paths from /WEBAPP_NAME to / (root):

Header edit Set-Cookie "^(.*; Path=)/WEBAPP_NAME/?(.*)" $1/$2

Alternative method - change cookie path from Tomcat:

I also tested setting the cookie path from Tomcat in the web.xml of my application:

<session-config>
    <session-timeout>30</session-timeout>
    <cookie-config>
        <http-only>true</http-only>
        <path>/</path> <!-- changes the path -->
        <name>COOKIENAME</name>
    </cookie-config>
</session-config>

Got the web.xml example from the question at https://stackoverflow.com/questions/12755499/how-to-change-jsessionid-cookie-path-to-server-root-in-spring-app-on-jetty