2

The Problem

When redirecting from a servlet using response.sendRedirect(redirect_url);, the JSESSIONID cookie is not passed by the browser to the destination. A new JSESSIONID is created for every redirect, and it is impossible to track the user.

Note: This problem is only occurring on my new server implementing https and a domain name; the session ID is properly tracked when I run the web app locally or on another server without SSL or a domain name. Edit: I have set up another site on my server without SSL, and the issue persists. This seems to narrow the issue down to having a reverse proxy Apache.

An Example

The Login servlet on my web app attempts to store the user information in a session attribute then redirects to the MyCards servlet. I am using a redirect so that the URL will display mydomain.com/MyCards instead of mydomain.com/Login. The MyCards servlet attemtps to access the session attribute but finds nothing, and therefore redirects back to the Login servlet. This worked perfectly before deploying the project on my new server with SSL and domain name.

My Setup

  • Ubuntu 20.04 on DigitalOcean droplet
  • Apache Web Server (apache2) ... I have enabled mod_sessions, not sure if that's relevant.
  • Tomcat 9
  • Reverse proxy in Apache VirtualHost to Tomcat (I can post my .conf file if requested)
  • A redirect in Apache VirtualHost from HTTP to HTTPS
  • JDK 11

Possible Solutions

  • Using a forward instead of a redirect. The session ID is not lost when using requestDispatcher.forward(request, response);. As I mentioned above, I want the URL to reflect the destination for an intuitive user experience, which does not occur when using a forward.

  • Implementing your own session cookie, as in this answer, and manually storing sessions with a map, as in this answer, which strongly advises against such a facility. Based on my understanding, doing so poses security threats to user data. Also, if the browser is not passing the JSESSIONID cookie, I don't understand why it would choose to pass the manually implemented cookie unless the SameSite attribute is set to None (also bad).

  • Verifying that the webapp's context.xml does not have cookies="false" configured. Done that.

  • Using encoded URLs with response.sendRedirect(response.encodeRedirectURL(url));. Again, for the sake of having a clean URL (which the user could bookmark or type in) is preferable, and encoding the session ID into the URL is not.

  • Using relative URLs instead of absolute URLs... "A session is only maintained if the redirection is being sent on the same port, host and webapp [and protocol?]. If redirection is done within the same application, using relative paths is the best practice." I tried both redirect_url = "/MyCards" and redirect_url = "MyCards", no luck.

Possible Reasons

  • Perhaps I am unknowingly switching between HTTP and HTTPS, which is a change in protocol and will not preserve the session ID. Of course, my intention is to remain secure and stay exclusively in HTTPS. Edit: I have set up another site on my server without SSL, and the issue persists. This seems to narrow the issue down to having a reverse proxy Apache. When accessing the web app directly on Tomcat (i.e. with <server_ip>:8080/MyWebApp), the session is tracked properly on redirect. However when using mydomain.com, the session ID is lost on every redirect.

  • Something to do with naked domains.

  • Other?

  • Edit: Maybe the issue is occurring because of the way the client, Apache, and Tomcat interact via the reverse proxy. Does the proxy cause the domain/port to change on every request/response?

My Questions

  1. Why exactly is the session ID lost when using a redirect to a relative URL to a servlet in the same web app on the same server? Shouldn't the redirect occur entirely on the server-side, preventing a new request/session from being created? Since the relative URLs (which I thought would preserve the session) did not solve the issue, does this indicate some problem with my server setup (e.g. unintentional switching between protocols)?

  2. What is the best practice for maintaining the user session ID, even when the user has cookies disabled? Is there no way around URL encoding when cookies are disabled? Or should the app be implemented exclusively with forwards rather than redirects? If so, is there a workaround to changing the URL to reflect the destination?

Note: this is my first post, so I don't have the reputation to comment. I will edit the post with any needed information.

skoooozy
  • 33
  • 6
  • [All I had to do was add `sessionCookiePath="/"` to my context.xml root node](https://stackoverflow.com/a/4040972/12654533). – skoooozy Dec 15 '21 at 00:13

0 Answers0