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

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

内容简介: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)咨询。


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

查看所有标签

猜你喜欢:

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

Don't Make Me Think

Don't Make Me Think

Steve Krug / New Riders Press / 18 August, 2005 / $35.00

Five years and more than 100,000 copies after it was first published, it's hard to imagine anyone working in Web design who hasn't read Steve Krug's "instant classic" on Web usability, but people are ......一起来看看 《Don't Make Me Think》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

URL 编码/解码
URL 编码/解码

URL 编码/解码