shiro session存redis
来源:互联网 发布:非结构化数据的处理 编辑:程序博客网 时间:2024/06/07 05:00
先看配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <description>Shiro安全配置</description><context:property-placeholder ignore-unresolvable="true" location="classpath:cookie.properties"/> <!-- 安全认证过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/common/login"/> <property name="unauthorizedUrl" value="/error/403"/> <property name="successUrl" value="/admins/indexed/index"></property> <property name="filters"> <map> <entry key="exec"> <bean class="com.mark.demo.shiro.security.filter.SimpleExecutiveFilter"/> </entry> <entry key="authc"> <bean class="com.mark.demo.shiro.security.filter.AuthenticationFilter"> <property name="rememberMeParam" value="rememberMe"/> </bean> </entry> <entry key="roles"> <bean class="org.apache.shiro.web.filter.authz.RolesAuthorizationFilter"/> </entry> </map> </property> <property name="filterChainDefinitions"> <value> /js/** = anon,exec /css/** = anon,exec /video/** = anon,exec /upload/** = anon,exec /uploads/** = anon,exec /fonts/** = anon,exec /getAuthPrice/** = anon,exec /common/login/** = anon,exec /common/forgotpass/** = anon,exec /menu/** = authc,exec /brand/** = authc,exec /common/** = authc,exec /admins/** = authc,exec </value> </property> </bean> <!-- 定义授权缓存管理器 --> <bean id="shiroCacheManager" class="com.mark.demo.shiro.security.cache.RedisCacheManager"/> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!-- SHIRO 认证匹配 --> <bean id="userCredentialsMatcher" class="com.mark.demo.shiro.security.UserCredentialsMatcher"/> <!-- 系统安全认证 --> <bean id="userAuthorizingRealm" class="com.mark.demo.shiro.security.MysqlRealm"> <property name="credentialsMatcher" ref="userCredentialsMatcher"/> <property name="sessionDAO" ref="sessionDAO"/> <property name="userMapper" ref="userMapper"></property> </bean> <!-- 自定义会话 --> <bean id="sessionDAO" class="com.mark.demo.shiro.security.session.RedisSessionDAO"> <property name="sessionIdGenerator"> <bean class="com.mark.demo.shiro.security.utils.IdGen"/> </property> </bean> <!-- 指定本系统SESSIONID, 默认为: JSESSIONID --> <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg name="name" value="${cookie.session}"/> <property name="domain" value="${cookie.domain}"/> <property name="path" value="${cookie.path}"/> <property name="httpOnly" value="true"/> </bean> <!-- 指定本系统REMEMBERID --> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg name="name" value="${cookie.remember}"/> <property name="domain" value="${cookie.domain}"/> <property name="path" value="${cookie.path}"/> <property name="httpOnly" value="true"/> <property name="maxAge" value="2592000"/> </bean> <!-- 自定义会话管理配置 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionDAO" ref="sessionDAO"/> <property name="globalSessionTimeout" value="1800000"/> <property name="sessionValidationInterval" value="120000"/> <property name="sessionValidationSchedulerEnabled" value="true"/> <property name="sessionIdCookie" ref="sessionIdCookie"/> <property name="sessionIdCookieEnabled" value="true"/> </bean> <!-- rememberMe管理器 --> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/> <property name="cookie" ref="rememberMeCookie"/> </bean> <!-- 定义Shiro安全管理配置 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="userAuthorizingRealm"/> <property name="rememberMeManager" ref="rememberMeManager"/> <property name="sessionManager" ref="sessionManager"/> <property name="cacheManager" ref="shiroCacheManager"/> <property name="sessionMode" value="http"></property> </bean> <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/> <property name="arguments" ref="securityManager"/> </bean></beans>
主要就是实现
com.mark.demo.shiro.security.session.RedisSessionDAO
当session有更新时就会使用这个dao更新redis里的缓存
package com.mark.demo.shiro.security.session;import java.util.Collection;import org.apache.shiro.session.Session;public interface CustomSessionDAO extends org.apache.shiro.session.mgt.eis.SessionDAO{ /** * 获取活动会话 * @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话) * @return */ Collection<Session> getActiveSessions(boolean includeLeave); /** * 获取活动会话 * @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话) * @param principal 根据登录者对象获取活动会话 * @param filterSession 不为空,则过滤掉(不包含)这个会话。 * @return */ Collection<Session> getActiveSessions(boolean includeLeave, Object principal, Session filterSession);}
package com.mark.demo.shiro.security.session;import java.io.Serializable;import java.util.Collection;import java.util.Date;import java.util.Map;import java.util.Set;import org.apache.shiro.SecurityUtils;import org.apache.shiro.session.Session;import org.apache.shiro.session.UnknownSessionException;import org.apache.shiro.session.mgt.SimpleSession;import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;import org.apache.shiro.subject.SimplePrincipalCollection;import org.apache.shiro.subject.support.DefaultSubjectContext;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.google.common.collect.Sets;import com.mark.demo.shiro.entity.User;import com.mark.demo.shiro.utils.JedisUtils;import com.mark.demo.shiro.utils.StringUtils;public class RedisSessionDAO extends AbstractSessionDAO implements CustomSessionDAO{ private static final Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); public static final String SESSION_GROUPS = "redis_shiro_session_group"; public static final String SESSION_PREFIX = "session_"; @Override public void update(Session session) throws UnknownSessionException { if (session == null || session.getId() == null) { return; } String key = String.valueOf(SESSION_PREFIX + session.getId()); int timeoutSeconds = (int) (session.getTimeout() / 1000); JedisUtils.setObject(key, session, timeoutSeconds); User principal = null; SimplePrincipalCollection collection = (SimplePrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); if (null != collection) { principal = (User) collection.getPrimaryPrincipal(); } String principalId = principal != null ? principal.getId()+"": StringUtils.EMPTY; JedisUtils.setMapField(SESSION_GROUPS, key, principalId + "|" + session.getTimeout() + "|" + session.getLastAccessTime().getTime()); } /** * 清空会话及缓存 */ public static void clean() { Map<String, String> map=JedisUtils.getMap(SESSION_GROUPS); JedisUtils.del(SESSION_GROUPS); for (Map.Entry<String, String> entry : map.entrySet()) { JedisUtils.del(entry.getKey()); if (logger.isDebugEnabled()) { logger.debug("remove session {} ", entry.getKey()); } } } @Override public void delete(Session session) { if (session == null || session.getId() == null) { return; } String key = String.valueOf(SESSION_PREFIX + session.getId()); JedisUtils.removeMapField(SESSION_GROUPS,key); JedisUtils.del(key); } @Override public Collection<Session> getActiveSessions() { return getActiveSessions(true); } /** * 获取活动会话 * @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话) * @return */ @Override public Collection<Session> getActiveSessions(boolean includeLeave) { return getActiveSessions(includeLeave, null, null); } /** * 获取活动会话 * @param includeLeave 是否包括离线(最后访问时间大于3分钟为离线会话) * @param principal 根据登录者对象获取活动会话 * @param filterSession 不为空,则过滤掉(不包含)这个会话。 * @return */ @Override public Collection<Session> getActiveSessions(boolean includeLeave, Object principal, Session filterSession) { Set<Session> sessions = Sets.newHashSet(); try { Map<String, String> map =JedisUtils.getMap(SESSION_GROUPS); if(map==null){ return sessions; } for (Map.Entry<String, String> e : map.entrySet()) { if (StringUtils.isNotBlank(e.getKey()) && StringUtils.isNotBlank(e.getValue())) { String[] ss = StringUtils.split(e.getValue(), "|"); if (ss != null && ss.length == 3) { SimpleSession session = new SimpleSession(); session.setId(e.getKey()); session.setAttribute("principalId", ss[0]); session.setTimeout(Long.valueOf(ss[1])); session.setLastAccessTime(new Date(Long.valueOf(ss[2]))); try { // 验证SESSION session.validate(); boolean isActiveSession = false; // 不包括离线并符合最后访问时间小于等于3分钟条件。 if (includeLeave ) { isActiveSession = true; } // 过滤掉的SESSION if (filterSession != null && filterSession.getId().equals(session.getId())) { isActiveSession = false; } if (isActiveSession) { sessions.add(session); } } // SESSION验证失败 catch (Exception e2) { JedisUtils.removeMapField(SESSION_GROUPS, e.getKey()); JedisUtils.del(e.getKey()); } } // 存储的SESSION不符合规则 else { JedisUtils.removeMapField(SESSION_GROUPS, e.getKey()); JedisUtils.del(e.getKey()); } } // 存储的SESSION无Value else if (StringUtils.isNotBlank(e.getKey())) { JedisUtils.removeMapField(SESSION_GROUPS, e.getKey()); JedisUtils.del(e.getKey()); } } logger.info("getActiveSessions size: {} ", sessions.size()); } catch (Exception e) { logger.error("getActiveSessions", e); } return sessions; } @Override protected Serializable doCreate(Session session) { Serializable sessionId = this.generateSessionId(session); this.assignSessionId(session, sessionId); this.update(session); // SecurityUtils.getSubject() return sessionId; } @Override protected Session doReadSession(Serializable sessionId) { Session session = null; try { String key = String.valueOf(SESSION_PREFIX + sessionId); session = (Session) JedisUtils.getObject(key); } catch (Exception e) { logger.error("doReadSession {} {}", sessionId, e); } return session; } @Override public Session readSession(Serializable sessionId) throws UnknownSessionException { try { return super.readSession(sessionId); } catch (UnknownSessionException e) { return null; } }}demo地址:https://github.com/13567436138/shiro-demo
阅读全文
0 0
- shiro session存redis
- shiro redis session共享
- Nginx shiro redis 多tomcat共享session
- Redis与mybatis,shiro,spring session整合
- shiro+redis实现session共享<1>
- shiro+redis实现session共享<2>
- shiro+redis实现session共享<3>
- spring+shiro+redis实现session共享
- spring,shiro,redis实现session共享
- Nginx shiro redis 多tomcat共享session
- spring+redis+shiro 实现session共享
- apache shiro分布式session共享实战(redis版)
- 我的shiro之旅-session共享-redis
- 使用redis进行基于shiro的session集群共享
- 使用redis进行基于shiro的session集群共享
- Shiro与Redis集成,集群下的session共享
- shiro 使用redis 频繁请求获取session的问题
- spring boot整合redis实现shiro的分布式session共享
- 深入理解JS原型及其扩展
- 455. Assign Cookies
- 2017年暑假与南宁邀请赛总结
- geotrellis使用(三十二)大量GeoTiff文件实时发布TMS服务
- Top-K in MapReduce Haddop Framework
- shiro session存redis
- JavaScript : Array.prototype.concat()中涉及嵌套数组
- Search Range in Binary Search Tree
- 《自己动手写操作系统》实践(一)
- 非常可乐 HDU
- 461_Hamming_Distance
- 双列集合
- Lua 变量和赋值运算
- adb应用安装失败分析