I have read apache tomcat documentation a day before, and I am so confused about emptySessionPath . Up to my knowledge, if it's set to true, the emptySessionPath is stored at the root folder of web application. Please give the right definition of the term emptySessionPath and what happens if it is set to true and false?
Please guide me.Thanks in advance.
The emptySessionPath field just states whether the all cookie should be stored in the root URL path / (if emptySessionPath=true) or not (otherwise).
This is used by Apache's Connector. See details here (This is for AJP Connector, which is part of the Connnector object).
What this basically means is:
If emptySessionPath is enabled in
tomcat, the JSESSIONID cookie is
written to the root "/" path. This
means that whatever webapp you are on
will use the same cookie. Each webapp
will re-write the cookie's value to
hold that webapp's session id, and
they are all different.
When this is enabled and servlets in
different webapps are used, requests
from the same user to different
servlets will end up overwriting the
cookie so that when the servlet is
again interacted with it will create
a new session and loose the session it
had already set up.
If emptySessionPath is not set, there
are multiple cookies in the browser,
one for each webapp (none at the
root), so different webapps are not
re-writing each other's cookie as
above.
JSESSIONID is the ID Session for your Webapp. See a full explanation here.
Update: This information about usage is somewhat outdated - see here for a more up-to-date information on how to set the Session path also for recent tomcat.
If emptySessionPath is set to true, it will eliminate the context path from JSESSIONID cookie.It will set a cookie path to /.This attribute can be used for cross application autehentication mechanism.
Session are, as you probably know, often maintained by a cookie. A cookie has two values that determines whether they should be returned by the browser for a certain request, cookieDomain and cookiePath. The cookiePath must match that of the request.
A request is made for
/some/request/for/this.html
Cookie would be returned with cookie path:
/
/some
/some/request
But not for cookie path:
/other
By spec, a session is not shared between different web applications, so if you have web application foo.war deployed under /foo, the session cookie path would, by default be set to /foo.
It seems Connector.emptySessionPath is a protected variable on Connector. I haven't read the code - but I guess it has something to do with Tomcat's single sign on or sharing sessions, where you login to one context and are authenticated in all - in which case the cookie path must be / for the session cookies.
Just in case, for the web_app version 3.0, the cookie configuration is standarized, so the equivalent to the AJP's emptySessionPath in webapp 3.0 is:
<session-config>
<cookie-config>
<path>/</path>
<secure>true</secure>
</cookie-config>
</session-config>
Related
I'm using Tomcat 7.0.84, and my web app uses the Servlet 3.0 deployment descriptor. The web.xml file contains this:
<session-config>
<cookie-config>
<name>JSESSIONID</name>
<http-only>false</http-only>
</cookie-config>
<tracking-mode>URL</tracking-mode>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
I have a desktop application that logs into the web app and establishes a session. In response to a user action, it invokes a URL in a browser. Since I want the browser to be logged in with the same session, I append the jsessionid path parameter like this:
http://server/contextroot/path/;jsessionid=8BDF744802E7850D5AA4AB6535163504
I close my browser completely so when the URL is spawned, no previous session cookies will be sent. (My default browser is chrome, and I verify this is the case.)
I also very in code that the URL tracking mode is enabled, by logging the return value of
ServletContext.getEffectiveSessionTrackingModes.
What I'm expecting is the browser request to automatically get the session indicated by the ;jsessionid parameter, but it is not happening. Each time Tomcat includes a new session cookie in its response.
This code used to work with a previous version of Tomcat (Probably 5.5) and the servlet 2.3 spec. I don't see anything in the Servlet 3.0 spec or Tomcat docs that indicate that this shouldn't work, and I'm all out of ideas.
Does anyone know why this isn't working as expected?
Here is how I got this to work:
In web.xml, I changed
<cookie-config>
<name>JSESSIONID</name>
<http-only>false</http-only>
</cookie-config>
to:
<cookie-config>
<name>jsessionid</name>
<http-only>false</http-only>
</cookie-config>
so that the session cookie name is now all lowercase, and exactly matches the name of the jsessionid path parameter.
Another way it worked was to change the path parameter name from jsessionid to JSESSIONID. This is because, in Tomcat, if you explictly configure a name for the session cookie, it uses that as the name of the path parameter used to pass in a session ID. This seems to be out of compliance with section 7.1.3 of the Servlet 3.0 spec, which says:
The session ID must be encoded as a path parameter in the URL string.
The name of the parameter must be jsessionid. Here is an example of a
URL containing encoded path information:
http://www.myserver.com/catalog/index.html;jsessionid=1234
However, it does comply with this excerpt from section 7.1.1:
If a web application configures a custom name for its session tracking
cookies, the same custom name will also be used as the name of the URI
parameter if the session id is encoded in the URL (provided that URL
rewriting has been enabled).
I needed to change JSESSIONID's domain to ".something.com" in a context.xml file:
<Context path="/test" sessionCookiePath="/" sessionCookieDomain=".something.com" useHttpOnly="true" />
After that, when I perform a httpSession.invalidate() the session is reset but JSESSIONID value does not change.
I'm using Java 7, Spring MVC and Tomcat 7. I also tried to remove the JSESSIONID cookie manually, but it seems that Tomcat or Spring are not letting I change its value.
This may difficult troubleshooting on my system. I'd like to know if it's possible to change this behavior either on Spring or in Tomcat.
I found the problem in Tomcat's documentation:
"Note: Once one web application using sessionCookiePath="/" obtains a session, all subsequent sessions for any other web application in the same host also configured with sessionCookiePath="/" will always use the same session ID. This holds even if the session is invalidated and a new one created. This makes session fixation protection more difficult and requires custom, Tomcat specific code to change the session ID shared by the multiple applications."
Source: http://tomcat.apache.org/tomcat-7.0-doc/config/context.html
The issue is related to cookie path, and not with domain
Assuming you're using Spring Security, you can configure the session logout handler to delete the cookie for you.
...
<logout delete-cookies="JSESSIONID">
...
Or, in Java configuration, in a WebSecurityConfigurerAdapter:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
...
.logout()
.deleteCookies("JSESSIONID");
}
If you're not using Spring Security, you can probably install a Filter object into Spring's existing filter chain to delete the Set-Cookie header in outgoing requests whose sessions have been invalidated (or on whatever condition you specify, at that point). This is more or less what Spring Security's logout handlers do, anyway.
I am confused about a couple things regarding cookies.
Why do I need to use/customize javax.servlet.http.Cookie class in order to implement a Remember me feature?
In my web.xml couldn't I just use?:
<session-config>
<session-timeout>10080</session-timeout>
</session-config>
Isn't it a security issue having cookies on a computer? Couldn't a cracker steal another user's cookie and hijack their session?
You don't - you just need to create an http session. Tomcat will either create a cookie or use a jsessionid URL parameter to maintain your session - this is part of the Java EE servlet specification. If you use a JSP then they automatically create http sessions. Various other things can cause sessions to be created also.
Yes, this is called session hijacking.
I'd like to have Tomcat automatically add a trailing slash to my app's context if the url is entered without it.
When I test with Jetty, it automatically adds the trailing slash to my app's context, but Tomcat doesn't do this.
I'm uncertain what the context will be named once deployed, as I'm handing the WAR off to someone else, so any resource references in HTML is all relative. Is there any way to have Tomcat automatically redirect to the same context with a trailing slash added?
Currently Using Tomcat 7 with Spring 3.
It's an old post, but as of Tomcat 7.0.67, you need to add the following attribute to your context.xml file:
<Context mapperContextRootRedirectEnabled="true">...</Context>
As per the 7.0.67 changelog:
Move the functionality that provides redirects for context roots and directories where a trailing / is added from the Mapper to the DefaultServlet. This enables such requests to be processed by any configured Valves and Filters before the redirect is made. This behaviour is configurable via the mapperContextRootRedirectEnabled and mapperDirectoryRedirectEnabled attributes of the Context which may be used to restore the previous behaviour.
And in the Tomcat context documentation:
mapperContextRootRedirectEnabled: If enabled, requests for a web application context root will be redirected (adding a trailing slash) if necessary by the Mapper rather than the default Servlet. This is more efficient but has the side effect of confirming that the context path exists. If not specified, the default value of false is used.
It seems that your application's web.xml has a mapping to "/*". A servlet-mapping to "/*" causes tomcat to pass the request as-is to the web application (i.e. does not redirect).
To properly redirect, you must change the "/*" mapping to just "/", the latter means the default servlet.
Tomcat adds a trailing slash automatically. Just test it with the example application supplied with Tomcat..
If - due to some special configuration - it does not, I'd write a Filter that examines the query string and redirects as needed by the application. Many times this is needed anyways (doing http->https redirections, etc.)
Have you tried playing with URL Rewrite on Tomcat?
This might help: http://code.google.com/p/urlrewritefilter/
If that does not help, take a look at this: URL rewrite in tomcat web.xml
Pat's excellent answer helped me dig up a few more details on this. It seems this is related to some quirks in some versions of Tomcat (Tomcat 7 at 7.0.67+, and Tomcat 8 between 8.29 and 8.37) having to do with session cookies and URL redirection.
The bottom line seems to be that if the java server creates path-specific session cookies with a slash at the end (like "/app_name/"), then the server must also do an automatic initial redirect (/app_name --> /app_name/) ... otherwise, the session cookie will not get sent with the request, and it will never look to the server like you have a valid session. The may cause a redirect loop from the app to the authentication.
There are configurations in Tomcat that control both behaviors, but as far as I can tell, they were essentially out-of-sync in these versions, such that one might get the cookie with the trailing slash, without getting the redirect. There are several related issues/changes in the Tomcat changelog:
https://tomcat.apache.org/tomcat-8.0-doc/changelog.html
As Pat has already noted, this is resolved by adding this attribute to your app's Context element:
<Context mapperContextRootRedirectEnabled="true">
In J2EE web application, how do I disable the default HttpSession creation?
We have our own way of tracking session, we don't use default jsp/servlet session but the default session sets cookie in browser which I would like to avoid. Right now on every JSP page we specify as session="false" in page directive but often some developers missing this part, so I am trying to find a common place where I can control default session.
I am trying to find a common place where I can control default session.
The answer is servletcontainer specific since that's the one responsible for session creation and management. The standard Servlet API isn't responsible for that. It's unclear which servletcontainer you you're using, so here's a Tomcat targeted answer: create your own <Manager>.
Alternatively, you can also entirely disable cookie support and rely on URL rewriting only (but not do it). This way sessions won't survive among requests. You can do this in in for example Tomcat by setting the cookie attribute of the <Context> element to false.
If you're using another servletcontainer, then you need to consult its documentation based on the newly learnt information and keywords here above, or just to mention here which one it is.