Redis-shrio集成:用redis实现shrio框架下的session共享

    xiaoxiao2021-12-14  21

     

      

    开局扯淡篇:现在互联网数据越来越大,所以对平台数据吞吐量越来越高,简单的框架已经无法满足系统需要,那么我们需要用到 分布式 ,以及缓存。这里主要总结一下分布式情况下,通过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即可。

     

    附原理图:

     

     

    .......

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    转载请注明原文地址: https://ju.6miu.com/read-964093.html

    最新回复(0)