How do I remove the jsessionid from URLs in JBoss EAP?
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 4.x
- 5.x
- 6.x
- 7.x
Issue
- For security or other requirements at times there is a need to remove the
jsessionidcompletely from any generated URLs. The default behaviour of the servlet container is to pass thejsessionidvia the URL and a cookie on the first request that accesses the session. In that case, if the client rejects the cookie, or cookies are not enabled, the session can still be tied to the request via thejsessionidin the URL. - How to remove jsessionid from the URL
Resolution
Disclaimer:Links contained herein to the external website(s) are provided for convenience only. Red Hat has not reviewed the links and is not responsible for the content or its availability. The inclusion of any link to an external website does not imply endorsement by Red Hat of the website or their entities, products or services. You agree that Red Hat is not responsible or liable for any loss or expenses that may result due to your use of (or reliance on) the external site or content.
EAP 6.x/7.x:
As per Servlet Content from jcp.org is not included.3.0 and Content from jcp.org is not included.3.1 specifications, use <tracking-mode> setting in web.xml to configure session tracking mechanism. (COOKIE, URL, and SSL can be specified). A combination of COOKIE or URL is allowed by default though the app has to be written to support URL tracking as well as it has to properly use Content from docs.oracle.com is not included.response.encodeURL() or Content from docs.oracle.com is not included.response.encodeRedirectURL() for the jsessionid to be encoded into URLs. Removing the URL setting will remove the jsessionid from URLs (= disabling URL rewriting) regardless of the application code.
So, you can use COOKIE only for session tracking by setting the following example configuration:
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
If your WAR is within an EAR that has a <session-config> block in its META-INF/jboss-all.xml, then ensure the <tracking-mode> is set in this EAR's META-INF/jboss-all.xmlas well.
Note that there is a Content from issues.jboss.org is not included.bug regarding this feature in EAP 6.0.x. Red Hat recommends using the latest versions of EAP 6, which contains the fix.
Please also refer to this article.
EAP 4.x/5.x:
Note: User cannot use the disableURLRewriting attribute in context.xml as described on Tomcat's Content from tomcat.apache.org is not included.documentation cannot be used because this feature was not introduced until Tomcat 6.0.30, but JBoss EAP 4.x/5.x are based on and fork from 6.0.13 and 6.0.15, respectively.
- The following
Filteris an adaptation from theFilterlisted in <Content from jira.jboss.org is not included.https://jira.jboss.org/jira/browse/JBSEAM-3018>. CreateJsessionIdRemoveFilter.javain code base
package com.example;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class JsessionIdRemoveFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
if (!(req instanceof HttpServletRequest)) {
chain.doFilter(req, res);
return;
}
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// Redirect requests with JSESSIONID in URL to clean version (old links bookmarked/stored by bots)
// This is ONLY triggered if the request did not also contain a JSESSIONID cookie! Which should be fine for bots...
if (request.isRequestedSessionIdFromURL()) {
String url = request.getRequestURL()
.append(request.getQueryString() != null ? "?"+request.getQueryString() : "")
.toString();
response.setHeader("Location", url);
response.sendError(HttpServletResponse.SC_MOVED_PERMANENTLY);
return;
}
// Prevent rendering of JSESSIONID in URLs for all outgoing links
HttpServletResponseWrapper wrappedResponse =
new HttpServletResponseWrapper(response) {
@Override
public String encodeRedirectUrl(String url) {
return url;
}
@Override
public String encodeRedirectURL(String url) {
return url;
}
@Override
public String encodeUrl(String url) {
return url;
}
@Override
public String encodeURL(String url) {
return url;
}
};
chain.doFilter(req, wrappedResponse);
}
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
}
}
- Then edit the
web.xmlto contain:
<filter>
<filter-name>JsessionIdRemoveFilter</filter-name>
<filter-class>com.example.JsessionIdRemoveFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>JsessionIdRemoveFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- So this filter-mapping indicates a default of applying filters only under ordinary client calls to the path or servlet. So here we would need to set dispatcher value for ERROR messages. A value of ERROR means the Filter will be applied under the error page mechanism. The dispatcher has four legal values: FORWARD, REQUEST, INCLUDE and ERROR. A value of FORWARD means the Filter will be applied under RequestDispatcher.forward() calls. A value of REQUEST means the Filter will be applied under ordinary client calls to the path or servlet. A value of INCLUDE means the Filter will applied under RequestDispatcher.include() calls.
<filter>
<filter-name>JsessionIdRemoveFilter</filter-name>
<filter-class>com.example.JsessionIdRemoveFilter</filter-class>
</filter>
<filter>
<filter-name>error</filter-name>
<filter-class>com.example.JsessionIdRemoveFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>JsessionIdRemoveFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>error</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-
Hence add the following instead of above contain in web.xml to filter the error page also.
-
Now, the
;jsessionidwill no longer show up in the URL in the browser. As noted in the JIRA the code was taken from, this solution effectively disables URL rewriting and also means the site no longer works without cookies, so for a good user experience, an additional cookie check is needed. -
If using Apache httpd as load balancer in front of JBoss EAP then another option would be configuring a rewrite rule at the Apache httpd layer with
mod_rewrite.
RewriteEngine On
RewriteRule ^([^;]+);jsessionid=[A-Za-z0-9\-\+\_\*]+\.[A-Za-z0-9]+(.*)$ $1$2 [L,R=301]
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.