分布式场景下的shrio的session共享

442 阅读1分钟

自定义RedisSessionDAO

继承AbstractSessionDAO后实现Session增删改查的几个方法,然后再分布式系统中所有的项目再需要存储或获取Session时都会走Redis操作,这样就做到了集群环境的Session共享了

@Component
public class RedisSessionDao extends AbstractSessionDAO {

    @Value("${session.redis.expireTime}")
    private long expireTime;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        this.assignSessionId(session, sessionId);
        redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.SECONDS);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        return sessionId == null ? null : (Session) redisTemplate.opsForValue().get(sessionId);
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        if (session != null && session.getId() != null) {
            session.setTimeout(expireTime * 1000);
            redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.SECONDS);
        }
    }

    @Override
    public void delete(Session session) {
        if (session != null && session.getId() != null) {
            redisTemplate.opsForValue().getOperations().delete(session.getId());
        }
    }

    @Override
    public Collection<Session> getActiveSessions() {
        return redisTemplate.keys("*");
    }

}

配置文件中添加上面用到的配置

###redis连接配置
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=foobared
### Session过期时间(秒)
session.redis.expireTime=3600

注入RedisSessionDao

上面只是我们自己实现的管理Session的方式,现在需要将其注入SessionManager中,并设置过期时间等相关参数。

@Bean
public DefaultWebSessionManager defaultWebSessionManager(RedisSessionDao redisSessionDao) {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    sessionManager.setGlobalSessionTimeout(expireTime * 1000);
    sessionManager.setDeleteInvalidSessions(true);
    sessionManager.setSessionDAO(redisSessionDao);
    sessionManager.setSessionValidationSchedulerEnabled(true);
    sessionManager.setDeleteInvalidSessions(true);
    /**
     * 修改Cookie中的SessionId的key,默认为JSESSIONID,自定义名称
     */
    sessionManager.setSessionIdCookie(new SimpleCookie("JSESSIONID"));
    return sessionManager;
}

再将SessionManager注入Shiro的安全管理器SecurityManage中

@Bean
public SecurityManager securityManager(UserAuthorizingRealm userRealm, RedisSessionDao redisSessionDao) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(userRealm);
    // 取消Cookie中的RememberMe参数
    securityManager.setRememberMeManager(null);
    securityManager.setSessionManager(defaultWebSessionManager(redisSessionDao));
    return securityManager;
}

基于Redis实现的Session共享就完成了