Apache Shiro去掉URL中的JSESSIONID

来源:互联网 发布:淘宝注册需要打电话吗 编辑:程序博客网 时间:2024/06/06 19:50

使用shiro过程中,有时url会遇到JSESSIONID这个小尾巴,去掉小尾巴的解决方法:

1、其实shiro在1.3.2版本已经解决了这个问题,只需配置一下参数即可。

!-- 会话管理配置 --><bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">         <!-- 会话超时时间,单位:毫秒  20m=1200000ms, 30m=1800000ms, 60m=3600000ms-->        <property name="globalSessionTimeout" value="1800000"/>        <property name="sessionValidationInterval" value="1200000"/>        <!-- 去掉 JSESSIONID -->        <property name="sessionIdUrlRewritingEnabled" value="false" />        <property name="sessionValidationSchedulerEnabled" value="true"/>        <property name="sessionDAO" ref="sessionDAO"/>        <property name="sessionIdCookie" ref="sessionIdCookie"/>        <property name="sessionIdCookieEnabled" value="true"/></bean>


2、低于1.3.2版本处理方法:(原理)在我们点击登陆之后会访问DefaultSecurityManager构建Subject。创建Subject之前会做很多事(创建cookie和session等等)其中会访问一下DefaultWebSessionManager的getReferencedSessionId方法。方法里面判断cookie里面是否有sessionid。肯定是没有的啦所以不会向request里面存放ShiroHttpServletRequest的3个静态属性。然后在org.apache.shiro.web.filter.authc.FormAuthenticationFilter登陆成功跳转页面的时候。issueSuccessRedirect方法里面会判断request是否有ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE如果有直接跳转到成功页面。具体判断的代码在ShiroHttpServletRequest里面的isRequestedSessionIdFromURL方法上。如果没有会在跳转成功页面url后面加上JSESSIONID。所以url上就多出了JSESSIONID.然后跳转首页时又会访问DefaultSecurityManager构建Subject。同样会进DefaultWebSessionManager的getReferencedSessionId方法这个时候sessionid有值所以request里面存放了

ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE。这就是为什么我们删掉JSESSIONID他又不加上的原因。因为你后面每次访问。构建subject的时候sessionid有值request的里面也有值他就不会在url上加JSESSIONID了啊。假设我们删除浏览器cookie这个时候没有了sessionid。我们访问当前地址。同样会创建Subject。由于sessionid没有了所以request里面就不会存值了。然后会进入org.apache.shiro.web.filter.authc.UserFilter判断subject是否有认证信息。没有会通过saveRequestAndRedirectToLogin跳转到登陆页面。saveRequestAndRedirectToLogin里面判断request是否有值没值又会在跳转页面的url上加上JSESSIONID。然后进入登陆界面的时候构建subject 创建session request里面存值。好了说完了。看不懂得自己脑补把。

[java] view plain copy
  1. private Serializable getReferencedSessionId(ServletRequest request, ServletResponse response) {  
  2.   
  3.         String id = getSessionIdCookieValue(request, response);  
  4.         if (id != null) {  
  5.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,  
  6.                     ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);  
  7.         } else {  
  8.             //not in a cookie, or cookie is disabled - try the request URI as a fallback (i.e. due to URL rewriting):  
  9.   
  10.             //try the URI path segment parameters first:  
  11.             id = getUriPathSegmentParamValue(request, ShiroHttpSession.DEFAULT_SESSION_ID_NAME);  
  12.   
  13.             if (id == null) {  
  14.                 //not a URI path segment parameter, try the query parameters:  
  15.                 String name = getSessionIdName();  
  16.                 id = request.getParameter(name);  
  17.                 if (id == null) {  
  18.                     //try lowercase:  
  19.                     id = request.getParameter(name.toLowerCase());  
  20.                 }  
  21.             }  
  22.             if (id != null) {  
  23.                 request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,  
  24.                         ShiroHttpServletRequest.URL_SESSION_ID_SOURCE);  
  25.             }  
  26.         }  
  27.         


[java] view plain copy
  1. public boolean isRequestedSessionIdFromURL() {  
  2.        if (isHttpSessions()) {  
  3.            return super.isRequestedSessionIdFromURL();  
  4.        } else {  
  5.            String value = (String) getAttribute(REFERENCED_SESSION_ID_SOURCE);  
  6.            return value != null && value.equals(URL_SESSION_ID_SOURCE);  
  7.        }  
  8.    }  

我的办法在每次跳转之前就判断sessionid是否有值。因为每次跳转之前subject就已经创建了session。至于如果禁用cookies。同样还是会在url上加上jsessionid。我们只是把判断给至前了。并没有修改原有逻辑。具体代码如下

[java] view plain copy
  1. /** 
  2.  * clear JSESSIONID in URL if session id is not null  
  3.  * {@link DefaultWebSessionManager} getReferencedSessionId 
  4.  * {@link ShiroHttpServletRequest} isRequestedSessionIdFromURL 
  5.  *  
  6.  * @author Infinite Justice 
  7.  */  
  8. public class UserFilter extends AccessControlFilter{  
  9.       
  10.     private Cookie sessionIdCookie;  
  11.       
  12.     public Cookie getSessionIdCookie() {  
  13.         return sessionIdCookie;  
  14.     }  
  15.   
  16.   
  17.     public void setSessionIdCookie(Cookie sessionIdCookie) {  
  18.         this.sessionIdCookie = sessionIdCookie;  
  19.     }  
  20.       
  21.     @Override  
  22.     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {  
  23.         if (isLoginRequest(request, response)) {  
  24.             return true;  
  25.         } else {  
  26.             Subject subject = getSubject(request, response);  
  27.             // If principal is not null, then the user is known and should be allowed access.  
  28.             return subject.getPrincipal() != null;  
  29.         }  
  30.     }  
  31.       
  32.     @Override  
  33.     protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {  
  34.         saveRequest(request);  
  35.         String sessionid = sessionIdCookie.readValue(WebUtils.toHttp(request), WebUtils.toHttp(response));  
  36.         // clear JSESSIONID in URL if session id is not null   
  37.         if(sessionid != null){  
  38.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);  
  39.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionid);  
  40.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);  
  41.         }  
  42.         redirectToLogin(request, response);  
  43.         return false;  
  44.     }  
  45. }  


[java] view plain copy
  1. /** 
  2.  * clear JSESSIONID in URL if session id is not null  
  3.  * {@link DefaultWebSessionManager} getReferencedSessionId 
  4.  * {@link ShiroHttpServletRequest} isRequestedSessionIdFromURL 
  5.  *  
  6.  * @author Infinite Justice 
  7.  */  
  8. public class LoginFilter extends FormAuthenticationFilter{  
  9.       
  10.     private Cookie sessionIdCookie;  
  11.       
  12.     public Cookie getSessionIdCookie() {  
  13.         return sessionIdCookie;  
  14.     }  
  15.   
  16.   
  17.     public void setSessionIdCookie(Cookie sessionIdCookie) {  
  18.         this.sessionIdCookie = sessionIdCookie;  
  19.     }  
  20.   
  21.   
  22.     @Override  
  23.     protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {  
  24.         request.setAttribute(getFailureKeyAttribute(), ae);  
  25.     }  
  26.       
  27.     @Override  
  28.     protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {  
  29.         String sessionid = sessionIdCookie.readValue(WebUtils.toHttp(request), WebUtils.toHttp(response));  
  30.         // clear JSESSIONID in URL if session id is not null   
  31.         if(sessionid != null){  
  32.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);  
  33.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionid);  
  34.             request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);  
  35.         }  
  36.         super.issueSuccessRedirect(request, response);  
  37.     }  
  38. }  

另一种解决办法:

[java] view plain copy
  1. public class RedisWebSessionManager extends DefaultWebSessionManager {  
  2.   
  3.     /** 
  4.      * Stores the Session's ID, usually as a Cookie, to associate with future requests. 
  5.      * @param session the session that was just{@link #createSession created}. 
  6.      */  
  7.     @Override  
  8.     protected void onStart(Session session, SessionContext context) {  
  9.         super.onStart(session, context);  
  10.         ServletRequest request = WebUtils.getRequest(context);  
  11.         request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);  
  12.     }  
  13.       
  14. }