redis实现session共享

单台服务器登录验证]

).用户通过浏览器直接访问服务器资源

).用户登录信息在单台机器上验证

 

[多台服务器登录验证]

).用户通过浏览器直接访问服务器资源

).用户登录信息在多台机器上验证登录信息

).此时需要共享服务器会话(如redis),所有服务器验证同一个会话

).会话ID,需要共享,在不同服务器之间(相同顶级域名可以共享

Cookie)

实现步骤

spring-shiro.xml 配置

<!-- cacheManager 指定缓存管理为Redis缓存管理,指定redis缓存前缀 -->
 <bean id="cacheShrioManager" class="org.crazycake.shiro.RedisCacheManager">
        <property name="redisManager" ref="redisShrioManager" />
        <property name="keyPrefix" value="trader:shiro:cache:"/>
    </bean>

    <!-- shiro redisManager 用redis缓存管理,共享会话 -->
    <bean id="redisShrioManager" class="org.crazycake.shiro.RedisManager">
        <property name="host" value="${redis.server.ip}"/>
        <property name="port" value="${redis.server.port}"/>
        <property name="expire" value="1800"/><!-- 30分钟-->

    </bean>

    <!-- sessionIdCookie的实现,用于重写覆盖容器默认的JSESSIONID -->
    <bean id="shareSessionCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!-- cookie的name,对应的默认是 JSESSIONID -->
        <constructor-arg name="name" value="jsID}" />
        <!-- jsessionId的path为 / 用于多个系统共享jsessionId -->
        <property name="path" value="/" />
        <!-- 会话超时时间,单位:秒 -->
        <property name="maxAge" value="36000" /> <!-- 30分钟-->
        <property name="httpOnly" value="true"/>
        <property name="domain" value="localhost"/><!-- 配置顶级域名-->
    </bean>
<!-- 定义 Shiro 主要业务对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
   <property name="sessionManager" ref="sessionManager" />
   <property name="cacheManager" ref="cacheShrioManager" />
   <property name="realm" ref="customizeAuthorizingRealm"/>

</bean>

 <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionIdCookie" ref="shareSessionCookie" />
        <property name="sessionDAO" ref="sessionRedisDao"/>
        <property name="sessionFactory" ref="onlineSessionFactory"/>
        <property name="sessionValidationSchedulerEnabled" value="true"></property>
        <property name="sessionValidationInterval" value="1800000"/>  <!-- 相隔多久检查一次session的有效性 301秒 -->
        <property name="globalSessionTimeout" value="1800000"/>  <!-- session 有效时间为300秒 (毫秒单位)-->

        <!--<property name="sessionIdCookie.domain" value=""/>-->
    </bean>

 

<!--

除特殊地址外,其它访问地址,都需要用户登录后,才可以访问
/** = user

-->

 

 

自定义会话 SessionRedisDao

package com.fx.spring.shiro.session.dao;

import com.fx.constant.SystemConstant;
import com.fx.db.redis.service.RedisService;
import com.fx.spring.shiro.session.util.SessionCacheUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.io.Serializable;

@Repository
public class SessionRedisDao extends EnterpriseCacheSessionDAO {

    private final static String redis_session_id = SystemConstant.ONLINEUSER.ADMIN_ONLINEUSER_SESSION ;
    Logger logger = LoggerFactory.getLogger(SessionRedisDao.class) ;

    @Autowired
 RedisService redisService;



    // 创建session,保存到数据库
 @Override
 protected Serializable doCreate(Session session) {
        Serializable sessionId = super.doCreate(session);
        redisService.set( redis_session_id + sessionId,session);
        redisService.expireCache(redis_session_id + sessionId, SessionCacheUtil.getSessionTimeoutMILLISECONDS());

        logger.debug("[SessionRedisDao create session ] sessionId:{} session:{}", redis_session_id + sessionId,session);
        return sessionId;
    }

    @Override
 protected Session doReadSession(Serializable sessionId) {

        Session session =null;
        Object object = redisService.get( redis_session_id + sessionId);
        if(object !=null && object instanceof Session){
            session = (Session)object;
        }else{
            session = super.doReadSession(sessionId);
        }
        logger.debug("[SessionRedisDao read session ] sessionId:{} session:{}", redis_session_id + sessionId,session);
        return session;
    }

    // 更新session的最后一次访问时间
 @Override
 protected void doUpdate(Session session) {
        try{
            logger.debug("[SessionRedisDao update session ] sessionId:{} session:{}", redis_session_id + session.getId(),session);
            redisService.set( redis_session_id + session.getId(),session);
            redisService.expireCache(redis_session_id + session.getId(), SessionCacheUtil.getSessionTimeoutMILLISECONDS());
        }catch (Exception e){

        }


    }

    @Override
 protected void doDelete(Session session) {
        redisService.remove( redis_session_id + session.getId());
        logger.debug("[SessionRedisDao delete session ] sessionId:{} session:{}", redis_session_id + session.getId(),session);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值