CAS_SHIRO_SESSION使用Redis共享的方式与结果

CAS_SHIRO_SESSION共享的问题

结构图:

系统架构

使用Shiro的Redis插件

单点登录成功,多点退出失败(某个应用退出以后,其它应用不受影响,仍然在线,无法达到退出要求),主要问题在与SingleSignOutFilter退出时只失效了HttpSession.而ShiroSession仍然有效,本来实现SingleSignOutHandler使用的SessionMappingStorage接口来解决,因为ServletHttpSession没有实现序列化接口而作罢.

    <dependency>
      <groupId>org.crazycake</groupId>
      <artifactId>shiro-redis</artifactId>
      <version>2.4.2.1-RELEASE</version>
    </dependency>

在Shiro配置中加入相应的配置

  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="sessionManager" ref="sessionManager" />
    <property name="cacheManager" ref="cacheManager"/>
    <property name="subjectFactory" ref="casSubjectFactory"></property>
    <property name="realm" ref="casRealm" />
</bean>

<bean id="casSubjectFactory" class="org.apache.shiro.cas.CasSubjectFactory"></bean>

<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    <property name="securityManager" ref="securityManager" />
</bean>
<bean id="cacheManager" class="org.crazycake.shiro.RedisCacheManager">
    <property name="redisManager" ref="redisManager"/>
</bean>

 <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
           <property name="globalSessionTimeout" value="3600000" />
     <property name="sessionDAO" ref="sessionDAO" />
           <property name="sessionIdCookie" ref="sessionIdCookie"/>
 </bean>

<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    <constructor-arg name="name" value="SHRIOSESSIONID"/>
</bean>
<bean id="sessionDAO" class="org.crazycake.shiro.RedisSessionDAO">
     <property name="redisManager" ref="redisManager" />
 </bean>
<!-- shiro redisManager -->
<bean id="redisManager" class="org.crazycake.shiro.RedisManager">
    <property name="host" value="127.0.0.1"/>
    <property name="port" value="6379"/>
    <property name="expire" value="1800"/>
    <!-- optional properties:
          <property name="timeout" value="10000"/>
          <property name="password" value="123456"/>
          -->
</bean>

tomcat-redis-session-manager

使用redis配置tomcat共享session,成功

分析:

分布式web server集群部署后需要实现session共享,针对 tomcat 服务器的实现方案多种多样,
比如 tomcat cluster session 广播、nginx IP hash策略、nginx sticky module等方案,
本文主要介绍了使用 redis 服务器进行 session 统一存储管理的共享方案。

必要环境:

  • java1.7
  • tomcat7
  • redis2.8

nginx 负载均衡配置

  1. 修改nginx conf配置文件加入
upstream tomcat {
    server 200.10.10.67:8110;
    server 200.10.10.67:8120;
    server 200.10.10.44:8110;
    server 200.10.10.66:8110;
}
  1. 配置 相应的server或者 location地址到 http://tomcat

tomcat session共享配置步骤

  1. 添加redis session集群依赖的jar包到 TOMCAT_BASE/lib 目录下

  2. 修改 TOMCAT_BASE/conf 目录下的 context.xml 文件,也可以是server.xml对应的地方,注意:Value在Manager的前面

        <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
        <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="localhost"
         port="6379"
         database="0"
         maxInactiveInterval="60"
         sessionPersistPolicies="PERSIST_POLICY_1,PERSIST_POLICY_2,.."
         sentinelMaster="SentinelMasterName"
         sentinels="sentinel-host-1:port,sentinel-host-2:port,.."/>
    

    属性解释:

    • host redis服务器地址
    • port redis服务器的端口号
    • database 要使用的redis数据库索引
    • maxInactiveInterval session最大空闲超时时间,如果不填则使用tomcat的超时时长,一般tomcat默认为1800 即半个小时
    • sessionPersistPolicies session保存策略,除了默认的策略还可以选择的策略有:

      [SAVE_ON_CHANGE]:每次 session.setAttribute() 、 session.removeAttribute() 触发都会保存. 
          注意:此功能无法检测已经存在redis的特定属性的变化,
          权衡:这种策略会略微降低会话的性能,任何改变都会保存到redis中.
      
      [ALWAYS_SAVE_AFTER_REQUEST]: 每一个request请求后都强制保存,无论是否检测到变化.
          注意:对于更改一个已经存储在redis中的会话属性,该选项特别有用. 
          权衡:如果不是所有的request请求都要求改变会话属性的话不推荐使用,因为会增加并发竞争的情况。
      
    • sentinelMaster redis集群主节点名称(Redis集群是以分片(Sharding)加主从的方式搭建,满足可扩展性的要求)
    • sentinels redis集群列表配置(类似zookeeper,通过多个Sentinel来提高系统的可用性)
    • connectionPoolMaxTotal
    • connectionPoolMaxIdle jedis最大能够保持idel状态的连接数
    • connectionPoolMinIdle 与connectionPoolMaxIdle相反
    • maxWaitMillis jedis池没有对象返回时,最大等待时间
    • minEvictableIdleTimeMillis
    • softMinEvictableIdleTimeMillis
    • numTestsPerEvictionRun
    • testOnCreate
    • testOnBorrow jedis调用borrowObject方法时,是否进行有效检查
    • testOnReturn jedis调用returnObject方法时,是否进行有效检查
    • testWhileIdle
    • timeBetweenEvictionRunsMillis
    • evictionPolicyClassName
    • blockWhenExhausted
    • jmxEnabled
    • jmxNameBase
    • jmxNamePrefix

  3. 重启tomcat,session存储即可生效
    可使用redis-cli keys * 查看登录成功后是否有相应的记录.其它客户端退出后是否删除.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值