Remove jsessionid from URL
Asked Answered
C

7

23

I'm working on a project with the following technologies:

  • Spring
  • ShiroFilter
  • PrettyFaces
  • Tomcat server

While I'm deploying it on tomcat server, I'm getting a "JSESSIONID 456jghd787aa" added at the end of the URL.

I was trying to resolve this but I'm not able to do that.

Corrinacorrine answered 4/7, 2012 at 10:51 Comment(0)
A
39

For tomcat 7 add this to web.xml

<session-config>
  <!-- Disables URL-based sessions (no more 'jsessionid' in the URL using Tomcat) -->
  <tracking-mode>COOKIE</tracking-mode>
</session-config>
Autoharp answered 4/7, 2012 at 10:56 Comment(4)
Actually I added this on web.xml but it was not yet resolved... Is there any other options :(Corrinacorrine
@Corrinacorrine Maybe you're using an old container or one that does not support this option?Anonymous
I'm using tomcat 7.x, servlet 3.0.1, shiro, spring, with this directive, and still get the jsessionid on urls. Any thoughts?Kriss
This only works with shiro's ServletContainerSessionManager and not with DefaultWebSessionManagerRabbitfish
R
7

The following filter may solve your problem (from http://randomcoder.org/maven/site/randomcoder-website/cobertura/org.randomcoder.security.DisableUrlSessionFilter.html)

package com.companyname.projectname.web.filter;

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;
import javax.servlet.http.HttpSession;

/**
 * Servlet filter which disables URL-encoded session identifiers.
 * 
 * <pre>
 * Copyright (c) 2006, Craig Condit. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *     
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * </pre>
 */
public class DisableUrlSessionFilter implements Filter {

/*    private static Log logger = LogFactory.getLog(DisableUrlSessionFilter.class);
*/
    /**
     * Filters requests to disable URL-based session identifiers.
     */
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // skip non-http requests
        if (!(request instanceof HttpServletRequest)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // clear session if session id in URL
        if (httpRequest.isRequestedSessionIdFromURL()) {
            HttpSession session = httpRequest.getSession();
            if (session != null) {
                session.invalidate();
            }
        }

        // wrap response to remove URL encoding
        HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(
                httpResponse) {
            @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;
            }
        };

        // process next request in chain
        chain.doFilter(request, wrappedResponse);
    }

    /**
     * Unused.
     */
    public void init(FilterConfig config) throws ServletException {
    }

    /**
     * Unused.
     */
    public void destroy() {
    }
}
Rewire answered 4/7, 2012 at 11:4 Comment(1)
This can also be achieved using a PrettyFaces rewrite rule: ocpsoft.org/support/topic/…Wylie
R
3
  • Tomcat 6, add disableURLRewriting="true" in your context.xml

  • Tomcat 7 and ServletFilter have already been discussed

  • Or programmatically :

servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));

Runner answered 12/3, 2013 at 7:18 Comment(0)
H
3

You can add that settings into your http tag as follows:

<http auto-config="false" disable-url-rewriting="true">
Hagi answered 3/6, 2013 at 21:40 Comment(0)
W
1

If you are not using Servlet 3.0, you can also achieve this using a PrettyFaces Rewrite Rule: http://ocpsoft.org/support/topic/url-rewrite-removing-the-jsessionid-from-the-url#post-410

Wylie answered 4/7, 2012 at 14:57 Comment(1)
Actually I also added this on my prettyfaces config file but still the jsession id appears in the first RequestCorrinacorrine
V
1

You'll want to take it out of Tomcat, as others have suggested, but you'll still have problems with Shiro appending it to the end on redirects if you don't have a cookie set yet. There are two open tickets on the problem:

https://issues.apache.org/jira/browse/SHIRO-360

https://issues.apache.org/jira/browse/SHIRO-361

I tried to get Tuckey's URL Re-write to work and had partial success after a while. The problem is Shiro doesn't call response.encodeURL() and therefore trip the outbound rules. I was able to redirect inbound requests to remove the session id with these two rules:

<rule>
    <note>Remove jsessionid from embedded urls - for urls WITH query parameters</note>
    <from>^/(.*);JSESSIONID=.*[?](.*)$</from>
    <to type="redirect">/$1?$2</to>
</rule>

<rule>
    <note>Remove jsessionid from embedded urls - for urls WITHOUT query parameters</note>
    <from>^/(.*);JSESSIONID=.*[^?]$</from>
    <to type="redirect">/$1</to>
</rule>

That at least makes it not show up in the browser, but it doesn't completely solve the problem, because the session ID was sent on the URL and the redirected to the location without it. It would be better if it never showed up at all.

UPDATE:

SHIRO-360 and SHIRO-361 have been fixed and the fixes are in Shiro 1.3.0. According Brian Demers in SHIRO-361:

Set sessionManager.sessionIdUrlRewritingEnabled = false to disable appending JSESSIONID to the URL.

NOTE: if a user has disabled cookies, they will NOT be able to login if this is disable.

Ventricose answered 19/11, 2014 at 21:37 Comment(0)
H
1

Jetty WebappContext:

Set<SessionTrackingMode> trackingModes = new HashSet<>();
trackingModes.add(SessionTrackingMode.COOKIE);
context.getSessionHandler().getSessionManager().setSessionTrackingModes(trackingModes);
Hamper answered 14/8, 2017 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.