Redis-shrio集成:用redis實現shrio框架下的session共享

 

  

開局扯淡篇:現在互聯網數據越來越大,所以對平臺數據吞吐量越來越高,簡單的框架已經無法滿足系統需要,那麼我們需要用到 分佈式 ,以及緩存。這裏主要總結一下分佈式情況下,通過jedis解決session共享以及單點登錄的問題。

 

建議:先初步瞭解下shrio再看此文章

使用的jar:

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-core</artifactId>

</dependency>

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-spring</artifactId>

</dependency>

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-cas</artifactId>

<exclusions>

<exclusion>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-web</artifactId>

</dependency>

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-ehcache</artifactId>

</dependency>

<dependency>

      <groupId>org.crazycake</groupId>

      <artifactId>shiro-redis</artifactId>

      <version>2.4.2.1-RELEASE</version>

</dependency>

這裏重點介紹的 org.crazycake  ,上面的shrio是我們常用的登錄驗證框架

 

看到這裏,希望能把org.crazycake的源碼down下來,然後對着看。因爲org.crazycake中重寫了shrio中的操作session的類,也是我們需要用到它的地方。

 

Shrio中最核心的類:org.apache.shiro.web.mgt.DefaultWebSecurityManager

他擁有3個重要的屬性 :realm(權限驗證器)、sessionManager(session管理器)、cacheManager(緩存管理器)

這裏需要區分一下:

sessionManager:字面意思,管理session的(這裏指shrio的session,不是HttpSession喔)

cacheManager:認證和授權管理器

我們這裏主要重新注入這兩個屬性。

 

吶,現在看下一下shrio的類結構圖

 

Org.crazycake,幫我們實現了 以上所有屬性,

sessionDAO:

org.crazycake.shiro.RedisSessionDAO 第25行:private String keyPrefix = "shiro_redis_session:";

可以看到我們存到redis緩存中的key前綴是"shiro_redis_session:"開頭的(也可以注入新的名稱)

sessionIdCookie:cookie機制存儲name屬性指定cookieId

redisManager:操作緩存的類

 

辣麼,以下配置正確的實現了上圖所有屬性:

<!-- shiro securityManager -->

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

    <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->

  <property name="realm" ref="systemAuthorizingRealm" />

    <!-- sessionManager -->

    <property name="sessionManager" ref="sessionManager" />

    <!-- cacheManager -->

    <property name="cacheManager" ref="cacheManager" />

    <!-- By default the servlet container sessions will be used.  Uncomment this line

         to use shiro's native sessions (see the JavaDoc for more): -->

    <!-- <property name="sessionMode" value="native"/> -->

</bean>

 

<!-- shiro redisManager -->

<bean id="redisManager" class="org.crazycake.shiro.RedisManager">

    <property name="host" value="${redisManager.host}"/>

    <property name="port" value="${redisManager.port}"/>

    <property name="expire" value="${redisManager.timeout}"/>

    <!-- optional properties:

    <property name="timeout" value="10000"/>

    <property name="password" value="123456"/>

    -->

</bean>

 

<!-- redisSessionDAO -->

<bean id="redisSessionDAO" class="org.crazycake.shiro.RedisSessionDAO">

    <property name="redisManager" ref="redisManager" />

    <property name="keyPrefix" value="${redisManager.prefix}"></property>

</bean>

 

<!-- sessionManager -->

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">

    <property name="sessionDAO" ref="redisSessionDAO" />

     <property name="sessionIdCookie" ref="sharesession" />  

</bean>

 

<!-- cacheManager -->

<bean id="cacheManager" class="org.crazycake.shiro.RedisCacheManager">

    <property name="redisManager" ref="redisManager" />

</bean>

<!-- 安全認證過濾器 -->

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">

<property name="securityManager" ref="securityManager" />

<property name="loginUrl" value="/index.html" />

<property name="filterChainDefinitions">

<ref bean="shiroFilterChainDefinitions"/>

</property>

</bean>

 <!-- sessionIdCookie的實現,用於重寫覆蓋容器默認的JSESSIONID -->  

    <bean id="sharesession" class="org.apache.shiro.web.servlet.SimpleCookie">  

        <!-- cookie的name,對應的默認是JSESSIONID -->  

        <constructor-arg name="name" value="${redisManager.sessionname}" />  

        <!-- jsessionId的path爲/用於多個系統共享jsessionId -->  

        <property name="path" value="/" />  

        <property name="httpOnly" value="false"/>  

    </bean>  

Java代碼中,通過SecurityUtils.getSubject().getSession()獲取session即可。

 

附原理圖:

 

 

.......

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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