Shiro安全框架基于Redis的分布式集群方案

栏目: Java · 发布时间: 6年前

内容简介:Shiro安全框架基于Redis的分布式集群方案

前段时间做了一个市场推广相关的项目,安全框架使用的是Shiro,缓存框架使用的是spring-data-redis。为了使用户7x24小时访问,决定把项目由单机升级为分布式部署架构。但是安全框架shiro只有单机存储的SessionDao,尽管Shrio有基于Ehcache-rmi的组播/广播实现,然而集群的分布往往是跨网段的,甚至是跨地域的,所以寻求新的方案。

运行环境

Nginx + Tomcat7(3台) + JDK1.7

项目架构图

Shiro安全框架基于 <a href='https://www.codercto.com/topics/18994.html'>Redis</a> 的分布式集群方案

Shiro安全框架基于Redis的分布式集群方案

项目实现

pom.xml引入配置(版本自行更换):

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>1.7.10.RELEASE</version>
</dependency>

redis.properties配置:

#============================#
#===== redis sttings     ====#
#============================#
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
#单位秒
redis.expire=1800
redis.timeout=2000
redis.usepool=true
redis.database=1

spring-context-redis.xml配置:

<!-- redis 配置 -->
	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig" />

	<bean id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
		<property name="hostName" value="${redis.host}" />
		<property name="port" value="${redis.port}" />
		<property name="password" value="${redis.password}" />
		<property name="timeout" value="${redis.timeout}" />
		<property name="poolConfig" ref="jedisPoolConfig" />
		<property name="usePool" value="true" />
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
	</bean>

RedisSessionDAO配置(重写 AbstractSessionDAO):

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
/**
 * 重写 AbstractSessionDAO
 * 使用Redis缓存
 * 创建者 张志朋
 * 创建时间	2018年1月10日
 */
public class RedisSessionDAO extends AbstractSessionDAO {

	private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);
	/**
	 * shiro-redis的session对象前缀
	 */
	private RedisTemplate<String, Object> redisTemplate;
	// 0 - never expire
	private int expire = 3600000;
	
	
	/**
	 * The Redis key prefix for the sessions 
	 */
	private String keyPrefix = "shiro_market_redis_session:";
	
	@Override
	public void update(Session session) throws UnknownSessionException {
		this.saveSession(session);
	}
	
	/**
	 * save session
	 * @param session
	 * @throws UnknownSessionException
	 */
	private void saveSession(Session session) throws UnknownSessionException{
		if(session == null || session.getId() == null){
			logger.error("session or session id is null");
			return;
		}
		
		String key = session.getId().toString();
		session.setTimeout(expire);		
		redisTemplate.opsForValue().set(keyPrefix+key, session, expire, TimeUnit.MILLISECONDS);
	}

	@Override
	public void delete(Session session) {
		if(session == null || session.getId() == null){
			logger.error("session or session id is null");
			return;
		}
		redisTemplate.delete(keyPrefix+session.getId().toString());

	}

	@Override
	public Collection<Session> getActiveSessions() {
		Set<Session> sessions = new HashSet<Session>();
		Set<String> keys = redisTemplate.keys(this.keyPrefix + "*");
		if(keys != null && keys.size()>0){
			for(String key:keys){
				Session s = (Session)redisTemplate.opsForValue().get(key);
				sessions.add(s);
			}
		}
		
		return sessions;
	}

	@Override
	protected Serializable doCreate(Session session) {
		Serializable sessionId = this.generateSessionId(session);  
        this.assignSessionId(session, sessionId);
        this.saveSession(session);
		return sessionId;
	}

	@Override
	protected Session doReadSession(Serializable sessionId) {
		if(sessionId == null){
			logger.error("session id is null");
			return null;
		}
		Session s = (Session)redisTemplate.opsForValue().get(keyPrefix+sessionId);
		return s;
	}
	
	/**
	 * Returns the Redis session keys
	 * prefix.
	 * @return The prefix
	 */
	public String getKeyPrefix() {
		return keyPrefix;
	}

	/**
	 * Sets the Redis sessions key 
	 * prefix.
	 * @param keyPrefix The prefix
	 */
	public void setKeyPrefix(String keyPrefix) {
		this.keyPrefix = keyPrefix;
	}

	public RedisTemplate<String, Object> getRedisTemplate() {
		return redisTemplate;
	}

	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
}

spring-shiro.xml配置:

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
	    <!-- 会话超时时间,单位:毫秒  20m=1200000ms, 30m=1800000ms, 60m=3600000ms-->
		<!-- 设置session过期时间为1小时(单位:毫秒),默认为30分钟 -->
        <!-- 如果设置 Redis缓存 此处不生效将 -->
		<property name="globalSessionTimeout" value="3600000"></property>
		<property name="sessionValidationSchedulerEnabled" value="true"></property>
		<property name="sessionIdUrlRewritingEnabled" value="false"></property>
		<!-- 注入 redisSessionDAO -->
		<property name="sessionDAO" ref="sessionDAO"/>
	</bean>

	<!-- redisSessionDAO -->
	<bean id="sessionDAO" class="com.acts.market.common.session.RedisSessionDAO">
		<property name="redisTemplate" ref="redisTemplate" />
	</bean>
Shiro安全框架基于Redis的分布式集群方案
Shiro安全框架基于Redis的分布式集群方案

作者:小柒

出处: https://blog.52itstyle.com

分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大家指正,共同进步。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 如有问题, 可邮件(345849402@qq.com)咨询。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

菜鸟侦探挑战数据分析

菜鸟侦探挑战数据分析

[日] 石田基广 / 支鹏浩 / 人民邮电出版社 / 2017-1 / 42

本书以小说的形式展开,讲述了主人公俵太从大学文科专业毕业后进入征信所,从零开始学习数据分析的故事。书中以主人公就职的征信所所在的商业街为舞台,选取贴近生活的案例,将平均值、t检验、卡方检验、相关、回归分析、文本挖掘以及时间序列分析等数据分析的基础知识融入到了生动有趣的侦探故事中,讲解由浅入深、寓教于乐,没有深奥的理论和晦涩的术语,同时提供了大量实际数据,使用免费自由软件RStudio引领读者进一步......一起来看看 《菜鸟侦探挑战数据分析》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试