WindySky / 我的shiro之旅 / 我的shiro之旅: 六 自定义shiro的sessionId

0 0

   

我的shiro之旅: 六 自定义shiro的sessionId

2017-12-27  WindySky

shiro有自己的sesison概念,shiro的session并不是java ee的session。通常,我们看到shiro的sessionId格式类似c6395bbc-425d-43b3-a444-04fee5a92e95,是因为shiro产生sesisonId是通过UUID生成的。我们可以看到shiro-core-xx.jar的org.apache.shiro.session.mgt.eis包下有个JavaUuidSessionIdGenerator,shiro的sessionId默认是通过该类生成的。可以看看源码。

  1. public class JavaUuidSessionIdGenerator implements SessionIdGenerator {  
  2.   
  3.     /** 
  4.      * Ignores the method argument and simply returns 
  5.      * {@code UUID}.{@link java.util.UUID#randomUUID() randomUUID()}.{@code toString()}. 
  6.      * 
  7.      * @param session the {@link Session} instance to which the ID will be applied. 
  8.      * @return the String value of the JDK's next {@link UUID#randomUUID() randomUUID()}. 
  9.      */  
  10.     public Serializable generateId(Session session) {  
  11.         return UUID.randomUUID().toString();  
  12.     }  
  13. }  

是通过调用java的UUID来生成一个唯一的ID。

我们可以自定义类,重写generateId方法,然后把它注入到shiro中。我们可以拿java ee的sessionId作为shiro的sessionId返回。不过我们可以看到generateId方法的参数是Session,这个Session是shiro自定义的,通过它无法拿到java ee的sessionId。我的做法是,写一个拦截器,当讲求过来时,拿到sessionId放到当前线程里,需要的时候从当前线程里拿。类也很简单,代码如下:

  1. /** 
  2.  * @author Dylan 
  3.  */  
  4. public final class HttpSessionIdHolder {  
  5.   
  6.     private HttpSessionIdHolder(){}  
  7.       
  8.     private final static ThreadLocal<String> SESSIONID = new ThreadLocal<String>();  
  9.       
  10.     /** 
  11.      * @return 
  12.      */  
  13.     public static String getSessionId(){  
  14.         return SESSIONID.get();  
  15.     }  
  16.       
  17.     /** 
  18.      * @param request 
  19.      */  
  20.     public static void setSessionId(String SessionId){  
  21.         SESSIONID.set(SessionId);  
  22.     }  
  23.       
  24.     /** 
  25.      *  
  26.      */  
  27.     public static void removeSessionId(){  
  28.         SESSIONID.remove();  
  29.     }  
  30.   
  31. }  
我们在拦截器里从request拿到sessionId,然后调用setSessionId方法把sessionId保存到当前线程中,需要的时候调用getSessionId就可以得到。

当然,也可以用其他方法。

那么,怎么注入给shiro替换默认的sessionId产生方式呢。在securityManager有个sessionManager属性,在sessionManager有个sessionDAO属性,在sessionDAO有个sessionIdGenerator只要替换就行。如

  1. <span style="white-space:pre;"> </span><bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  2.         <property name="sessionManager" ref="sessionManager"/>  
  3.     </bean>  
  4.     <bean id="sessionDAO" class="com.neting.security.infrastructure.shiro.cache.CustomShiroSessionDao">  
  5.         <property name="sessionIdGenerator" ref="sessionIdGenerator"/>  
  6.     </bean>  
  7.     <bean id="sessionIdGenerator" class="com.neting.security.infrastructure.shiro.ShiroSessionIdGenerator"/>  
  8.     <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  9.         <property name="sessionDAO" ref="sessionDAO"/>  
  10.     </bean>  

更简单的方式,在我的shiro之旅: 十 自定义shiro的SessionIdCookie这篇文章有介绍。




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多