shiro重定向時URL中的JSESSIONID問題

最近開始在項目中使用shiro作爲權限控制,配置成功後,訪問一切正常。但發現在向登錄頁面重定向時,URL中總是帶;JSESSIONID=****,這時Session的另一種使用方式(一種是Cookie)。本來也不影響使用,但是據說這種方式有漏洞,再就是這樣看着實在是不爽。那怎麼去掉呢?

第一步:剛開始我以爲是tomcat的問題,於是就百度了下tomcat怎麼取消url中的JSESSIONID。

https://fralef.me/tomcat-disable-jsessionid-in-url.html。因爲使用的是tomcat7,於是在wen.xml中配置

<session-config>
     <tracking-mode>COOKIE</tracking-mode>
</session-config>

也自定義配置了listener,但是怎麼弄都沒用

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

解決不了問題後,我在想可能不是tomcat的問題,於是想是在重定向時出現問題,那應該問題是在javax.servlet.http.HttpServletResponseWrapper.encodeRedirectURL方法時的問題,就開始debug找找問題的根源。

第二步:一步一步找到了問題

1、org.apache.shiro.web.filter.AccessControlFilter.redirectToLogin(ServletRequest, ServletResponse)

2、org.apache.shiro.web.util.RedirectView.sendRedirect(HttpServletRequest, HttpServletResponse, String, boolean)

protected void sendRedirect(HttpServletRequest request, HttpServletResponse response,
                                String targetUrl, boolean http10Compatible) throws IOException {
        if (http10Compatible) {
            // Always send status code 302.
            response.sendRedirect(response.encodeRedirectURL(targetUrl));
        } else {
            // Correct HTTP status code is 303, in particular for POST requests.
            response.setStatus(303);
            response.setHeader("Location", response.encodeRedirectURL(targetUrl));//<span style="color:#ff0000;">這裏調用了<span style="font-family: Arial, Helvetica, sans-serif;">response.encodeRedirectURL</span></span>

        }
    }
public String <span style="color:#ff0000;">encodeRedirectURL</span>(String url) {
        if (isEncodeable(toAbsolute(url))) {
            return toEncoded(url, request.getSession().getId());
        } else {
            return url;
        }
    }
protected String <span style="color:#ff0000;">toEncoded</span>(String url, String sessionId) {

        if ((url == null) || (sessionId == null))
            return (url);

        String path = url;
        String query = "";
        String anchor = "";
        int question = url.indexOf('?');
        if (question >= 0) {
            path = url.substring(0, question);
            query = url.substring(question);
        }
        int pound = path.indexOf('#');
        if (pound >= 0) {
            anchor = path.substring(pound);
            path = path.substring(0, pound);
        }
        StringBuilder sb = new StringBuilder(path);
        if (sb.length() > 0) { // session id param can't be first.
            sb.append(";");
            sb.append(DEFAULT_SESSION_ID_PARAMETER_NAME);//<span style="color:#ff0000;">在這裏加入了JSESSIONID</span>
            sb.append("=");
            sb.append(sessionId);
        }
        sb.append(anchor);
        sb.append(query);
        return (sb.toString());

    }

這樣就明白問題出在哪裏了。於是自定義MyShiroHttpServletResponse繼承ShiroHttpServletResponse,覆寫encodeRedirectURL直接返回url

                @Override
		public String encodeRedirectURL(String url) {
			// return super.encodeRedirectURL(url);
			return url;
		}
                @Override
<span style="white-space:pre">		</span>public String encodeURL(String url) {
<span style="white-space:pre">			</span>// return super.encodeURL(url);
<span style="white-space:pre">			</span>return url;
<span style="white-space:pre">		</span>}
在org.apache.shiro.web.servlet.ShiroFilter中覆寫wrapServletResponse方法,返回自定的ServletResponse包裝器

                @Override
		protected ServletResponse wrapServletResponse(HttpServletResponse orig, ShiroHttpServletRequest request) {
			// TODO Auto-generated method stub
			// return super.wrapServletResponse(orig, request);
			return MyShiroHttpServletResponse(orig, getServletContext(), request);
		}
問題解決了,也在過程中學習了servlet3的新特性


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章