最近開始在項目中使用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的新特性