Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSESSIONID collision between two servers on same ip but different ports

I've got a situation where I have two different webapps running on a single server, using different ports. They're both running Java's Jetty servlet container, so they both use a cookie parameter named JSESSIONID to track the session id. These two webapps are fighting over the session id.

  • Open a Firefox tab, and go to WebApp1
  • WebApp1's HTTP response has a set-cookie header with JSESSIONID=1
  • Firefox now has a Cookie header with JSESSIONID=1 in all it's HTTP requests to WebApp1
  • Open a second Firefox tab, and go to WebApp2
  • The HTTP reqeust to WebApp2 also has a Cookie header with JSESSIONID=1, but in the doGet, when I call req.getSession(false); I get null. And if I call req.getSession(true) I get a new Session object, but then the HTTP response from WebApp2 has a set-cookie header with JSESSIONID=20
  • Now, WebApp2 has a working Session, but WebApp1's session is gone. Going to WebApp1 will give me a new session, blowing away WebApp2's session.
  • Continue forever

So the Sessions are thrashing between each web app. I'd really like for the req.getSession(false) to return a valid session if there's already a JSESSIONID cookie defined.

One option is to basically reimplement the Session framework with a HashMap and cookies called WEBAPP1SESSIONID and WEBAPP2SESSIONID, but that sucks, and means I'll have to hack the new Session stuff into ActionServlet and a few other places.

This must be a problem others have encountered. Is Jetty's HttpServletRequest.getSession(boolean) just crappy?

like image 235
Steve Armstrong Avatar asked Jul 17 '09 23:07

Steve Armstrong


3 Answers

I had a similar problem: One or more instances of the same application on localhost on different ports, choosen at application start time, each using its own jetty instance.

After a while, I came up with this:

  • Wait for jetty to initialize
  • use jetty's SocketManager to get the port (socketManager.getLocalPort())
  • set the cookie name through the SessionManager (sessionHandler.getSessionManager().setSessionCookie(String))

This way I have a difference cookie name for each instance - thus no interference anymore.

like image 130
Moritz Both Avatar answered Nov 14 '22 23:11

Moritz Both


In our case we are using Tomcat, so the solution is to use different session cookie names on each instance.

In context.xml do something like

<Context sessionCookieName="JSessionId_8080">
like image 33
aij Avatar answered Nov 14 '22 22:11

aij


It's not Jetty's problem, it's how the cookie specification was defined. Beside the name/value pair, a cookie may also contain an expiration date, a path, a domain name, and whether the cookie is secure (i.e. intended only for SSL connections). The port number is not listed in the above ;-) so you'll need to vary either the path or the domain, as stepancheg says in his answer.

like image 3
Vinay Sajip Avatar answered Nov 14 '22 22:11

Vinay Sajip