Remove jsessionid from URL

偶尔善良 提交于 2019-11-29 22:24:08

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>

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() {
    }
}
  • 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));

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

<http auto-config="false" disable-url-rewriting="true">

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.

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

Jetty WebappContext:

Set<SessionTrackingMode> trackingModes = new HashSet<>();
trackingModes.add(SessionTrackingMode.COOKIE);
context.getSessionHandler().getSessionManager().setSessionTrackingModes(trackingModes);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!