shiro+redis+springMvc整合配置及说明
2015-03-11 09:08
471 查看
技术背景:shiro安全框架,redis作缓存,再整合spring。
1、配置web.xml
<bean id="basicPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="${redis.pool.maxActive}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="maxWait" value="${redis.pool.maxWaitTime}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<!-- JedisPool configuration-->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg index="0" ref="basicPoolConfig" />
<constructor-arg index="1" value="${redis.host.ip}" />
<constructor-arg index="2" value="${redis.host.port}" />
</bean>
<!-- JedisPool manager -->
<bean id="jedisPoolManager" class="com.isoftstone.securityframework.support.redis.JedisPoolManager">
<property name="jedisPool" ref="jedisPool"></property>
</bean>
<!--redisCacheManager要实现org.apache.shiro.cache.CacheManager接口,让shiro使用redis的缓存-->
<bean id="redisCacheManager" class="com.securityframework.support.redis.RedisCacheManager">
<property name="redisManager" ref="jedisPoolManager"></property>
</bean>
<!-- Redis session dao -->
<!--redisSessionDAO继承实现了org.apache.shiro.session.mgt.eis.SessionDAO的AbstractSessionDAO-->
<bean id="redisSessionDAO" class="com.securityframework.support.redis.RedisSessionDAO">
<property name="redisManager" ref="jedisPoolManager"></property>
<property name="expire" value="${shiro.session.timeout}"></property>
</bean>
3、上述bean对应的类(我们自己重写的)
com.securityframework.local.PermissionManagerLocalImpl
com.securityframework.local.AccountManagerLocalImpl
com.securityframework.restful.client.web.shiro.realm.RestAuthRealm
com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager
com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter
com.securityframework.support.redis.JedisPoolManager
com.securityframework.support.redis.RedisCacheManager
com.securityframework.support.redis.RedisSessionDAO
(1)com.securityframework.local.PermissionManagerLocalImpl
对权限信息的增删改查
(2)com.securityframework.local.AccountManagerLocalImpl
对账号信息的增删改查
(3)com.securityframework.restful.client.web.shiro.realm.RestAuthRealm
在shiro学习和使用实例(2)——登陆认证和授权
有详细解释
(4)com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager
(5)com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter
(6)com.securityframework.support.redis.JedisPoolManager
(7)com.securityframework.support.redis.RedisCacheManager
(8)com.securityframework.support.redis.RedisSessionDAO
通过redis实现shiro的CacheManager接口,继承AbstractSessionDAO,实现shiro和redis的整合。
1、配置web.xml
<filter> <filter-name>ShiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>ShiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>2、配置spring-shiro.xml的配置文件
<!--shiro配置--> <!--securityManager是shiro核心部分--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="sessionManager" ref="webSessionManager" /> <property name="realm" ref="restfulAuthRealm"/> <property name="rememberMeManager.cookie.name" value="rememberMe"/> <property name="rememberMeManager.cookie.maxAge" value="${rememberMeManager.cookie.maxAge}"/> </bean> <!--配置shiro的sessionManager--> <bean id="webSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="sessionDAO" ref="redisSessionDAO"></property> </bean> <!--权限操作bean--> <bean id="permissionManager" class="com.securityframework.local.PermissionManagerLocalImpl" /> <!--账号操作bean--> <bean id="accountManagerImpl" class="com.securityframework.local.AccountManagerLocalImpl"/> <!--自定义realm--> <bean id ="restfulAuthRealm" class="com.isoftstone.securityframework.restful.client.web.shiro.realm.RestAuthRealm"> <property name="accountManagerImpl" ref="accountManagerImpl"></property> <property name="permissionManagerImpl" ref="permissionManager"></property> <property name="cacheManager" ref="redisCacheManager"></property> <property name="platformLabel"> <value>${platformLabel}</value> </property> </bean> <!--动态获取filterchaindefinitions,此处与下面ShiroFilter bean所引用的类对应--> <bean id="systemUrlChainManager" class="com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager"> <property name="permissionManager" ref="permissionManager"></property> <property name="platformLabel"> <value>${platformLabel}</value> </property> <property name="systemLabel"> <value>${systemLabel}</value> </property> </bean> <!--与web.xml中配置的filter同名,它对应的类原本是<code class="xml string">org.apache.shiro.spring.web.ShiroFilterFactoryBean,</code>--> <!--这里为了动态获取filterchaindefinitions改写了<code class="xml string">ShiroFilterFactoryBean类,它们的作用是一样的</code>--> <bean id="ShiroFilter" class="com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter"> <property name="urlChainManager" ref="systemUrlChainManager" /> <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="../../res/user/login.html"/> <property name="unauthorizedUrl" value="/html/413.html"/> <property name="filters"> <util:map> <entry key="authc"> <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/> </entry> </util:map> </property> <property name="filterChainDefinitions"> <value> /images/** =anon /help/** =anon /css/** = anon /easyui/** =anon /javascript/** =anon /commons/** =anon /jsplugin/** =anon /ueditor/** =anon /html/** =anon /index.html = anon / = anon /** = user </value> </property> </bean> <span><span class="comments"> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --></span><span></span></span> <pre name="code" class="java"> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <!--redis配置--><!-- basic jedis pool configuration -->
<bean id="basicPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="${redis.pool.maxActive}" />
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="maxWait" value="${redis.pool.maxWaitTime}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
</bean>
<!-- JedisPool configuration-->
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg index="0" ref="basicPoolConfig" />
<constructor-arg index="1" value="${redis.host.ip}" />
<constructor-arg index="2" value="${redis.host.port}" />
</bean>
<!-- JedisPool manager -->
<bean id="jedisPoolManager" class="com.isoftstone.securityframework.support.redis.JedisPoolManager">
<property name="jedisPool" ref="jedisPool"></property>
</bean>
<!--redisCacheManager要实现org.apache.shiro.cache.CacheManager接口,让shiro使用redis的缓存-->
<bean id="redisCacheManager" class="com.securityframework.support.redis.RedisCacheManager">
<property name="redisManager" ref="jedisPoolManager"></property>
</bean>
<!-- Redis session dao -->
<!--redisSessionDAO继承实现了org.apache.shiro.session.mgt.eis.SessionDAO的AbstractSessionDAO-->
<bean id="redisSessionDAO" class="com.securityframework.support.redis.RedisSessionDAO">
<property name="redisManager" ref="jedisPoolManager"></property>
<property name="expire" value="${shiro.session.timeout}"></property>
</bean>
3、上述bean对应的类(我们自己重写的)
com.securityframework.local.PermissionManagerLocalImpl
com.securityframework.local.AccountManagerLocalImpl
com.securityframework.restful.client.web.shiro.realm.RestAuthRealm
com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager
com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter
com.securityframework.support.redis.JedisPoolManager
com.securityframework.support.redis.RedisCacheManager
com.securityframework.support.redis.RedisSessionDAO
(1)com.securityframework.local.PermissionManagerLocalImpl
对权限信息的增删改查
(2)com.securityframework.local.AccountManagerLocalImpl
对账号信息的增删改查
(3)com.securityframework.restful.client.web.shiro.realm.RestAuthRealm
在shiro学习和使用实例(2)——登陆认证和授权
有详细解释
(4)com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager
public class RestUrlChainManager { PermissionManager permissionManager; private String platformLabel ; private String systemLabel; public Map<String,String> buildChainMap(){ Map<String,String> p = new HashMap<String,String>(); //获取权限信息,以便获得每个权限下面的资源 List<com.isoftstone.securityframework.api.Permission> perms = permissionManager.findSubsystemPermission(platformLabel, systemLabel); if(null != perms && perms.size() > 0){ System.out.println(" SystemUrlChainManager.buildChainMap----- STATUS_OK -----"); } if (null != perms){ String value ; for (int i = 0; i < perms.size(); i++) { value = ""; com.isoftstone.securityframework.api.Permission perm = perms.get(i); if(i == 0){ value = "authc," + perm.getPermissionName(); }else{ value = perm.getPermissionName(); } List<com.isoftstone.securityframework.api.Resource> resources = perm.getResources(); if(null != resources){ for (int j = 0; j < resources.size(); j++) { com.isoftstone.securityframework.api.Resource resource = resources.get(j); //格式{'mvc/web/usermgt/add.json','perms[com.securitycenter.user:ADD]'},它 //对应spring-shiro.xml配置文件中ShiroFilter bean下的filterChainDefinitions p.put(resource.getRes(), String.format("perms[%s]", value)); } } } } return p; } /** * setter和getter方法省略 **/ }RestUrlChainManager类中的buildChainMap方法是从数据库获取资源,组成动态的filterChainDefinitions,以便系统对所有的资源请求的拦截都可以动态可配置
(5)com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter
public Map<String,String> getChainFilterMap(){ return getUrlChainManager().buildChainMap(); } public void setFilterChainDefinitionMap(Map<String, String> filterChainDefinitionMap) { Map<String, String> allFilterChainDefinitionMap = getFilterChainDefinitionMap(); if (CollectionUtils.isEmpty(allFilterChainDefinitionMap)){ this.filterChainDefinitionMap = filterChainDefinitionMap; }else{ //add custom chain definition allFilterChainDefinitionMap.putAll(filterChainDefinitionMap); } } public void setFilterChainDefinitions(String definitions) { Ini ini = new Ini(); ini.load(definitions); //did they explicitly state a 'urls' section? Not necessary, but just in case: Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS); if (CollectionUtils.isEmpty(section)) { //no urls section. Since this _is_ a urls chain definition property, just assume the //default section contains only the definitions: section = ini.getSection(Ini.DEFAULT_SECTION_NAME); } setFilterChainDefinitionMap(section); //add custom path filter map try{ Map<String,String> permFilterMap = this.getChainFilterMap(); if(!CollectionUtils.isEmpty(permFilterMap)){ setFilterChainDefinitionMap(permFilterMap); } }catch(Exception ex){ log.error("Load custom path filters to shiro filter failure."); ex.printStackTrace(); } }RestAuthShiroFilter其实就是使用的
org.apache.shiro.spring.web.ShiroFilterFactoryBean,里面的方法完全一样,只是为了动态获取filterChainDefinitions在
ShiroFilterFactoryBean类的基础上,增改了上述三个方法。实现的目的就是将RestUrlChainManager组装的{资源,权限}map加入到filterChainDefinitions中,实现拦截。从而能够动态的维护shiro拦截器拦截的内容。
(6)com.securityframework.support.redis.JedisPoolManager
/** * JedisPool 管理类 * 用于单个redis 集群, 每个redis集群由master-salve组成 */ public class JedisPoolManager { private static Log log = LogFactory.getLog(JedisPoolManager.class); private JedisPool jedisPool; /** * redis的List集合 ,向key这个list添加元素 */ public long rpush(String key, String string) { Jedis jedis = null; try { jedis = jedisPool.getResource(); long ret = jedis.rpush(key, string); jedisPool.returnResource(jedis); return ret; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 获取key这个List,从第几个元素到第几个元素 LRANGE key start * stop返回列表key中指定区间内的元素,区间以偏移量start和stop指定。 * 下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。 * 也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。 */ public List<String> lrange(String key, long start, long end) { Jedis jedis = null; try { jedis = jedisPool.getResource(); List<String> ret = jedis.lrange(key, start, end); jedisPool.returnResource(jedis); return ret; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 将哈希表key中的域field的值设为value。 */ public void hset(String key, String field, String value) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.hset(key, field, value); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 向key赋值 */ public void set(String key, String value) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.set(key, value); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 向key赋值 */ public void set(byte[] key, byte[] value) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.set(key, value); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 获取key的值 */ public String get(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); String value = jedis.get(key); jedisPool.returnResource(jedis); return value; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 获取key的值 */ public byte[] get(byte[] key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); byte[] value = jedis.get(key); jedisPool.returnResource(jedis); return value; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 将多个field - value(域-值)对设置到哈希表key中。 */ public void hmset(String key, Map<String, String> map) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.hmset(key, map); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 给key赋值,并生命周期设置为seconds */ public void setex(String key, int seconds, String value) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.setex(key, seconds, value); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 给key赋值,并生命周期设置为seconds */ public byte[] setex(byte[] key, byte[] value, int seconds) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.setex(key, seconds, value); jedisPool.returnResource(jedis); return value; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 为给定key设置生命周期 */ public void expire(String key, int seconds) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.expire(key, seconds); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 检查key是否存在 */ public boolean exists(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); boolean bool = jedis.exists(key); jedisPool.returnResource(jedis); return bool; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 检查key是否存在 */ public boolean exists(byte[] key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Set<byte[]> hashSet = jedis.keys(key); jedisPool.returnResource(jedis); if (null != hashSet && hashSet.size() >0 ){ return true; }else{ return false; } } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 返回key值的类型 none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表) */ public String type(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); String type = jedis.type(key); jedisPool.returnResource(jedis); return type; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 从哈希表key中获取field的value */ public String hget(String key, String field) { Jedis jedis = null; try { jedis = jedisPool.getResource(); String value = jedis.hget(key, field); jedisPool.returnResource(jedis); return value; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 返回哈希表key中,所有的域和值 */ public Map<String, String> hgetAll(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Map<String, String> map = jedis.hgetAll(key); jedisPool.returnResource(jedis); return map; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 返回哈希表key中,所有的域和值 */ public Set<?> smembers(String key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Set<?> set = jedis.smembers(key); jedisPool.returnResource(jedis); return set; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 返回匹配的 keys 列表 */ public Set<byte[]> keys(String pattern) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Set<byte[]> keys = jedis.keys(pattern.getBytes()); jedisPool.returnResource(jedis); return keys; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 移除set集合中的member元素 */ public void delSetObj(String key, String field) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.srem(key, field); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 删除元素 */ public void del(byte[] key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.del(key); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 判断member元素是否是集合key的成员。是(true),否则(false) */ public boolean isNotField(String key, String field) { Jedis jedis = null; try { jedis = jedisPool.getResource(); boolean bool = jedis.sismember(key, field); jedisPool.returnResource(jedis); return bool; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 如果key已经存在并且是一个字符串,将value追加到key原来的值之后 */ public void append(String key, String value) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.append(key, value); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 清空当前的redis 库 */ public void flushDB() { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.flushDB(); jedisPool.returnResource(jedis); } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 返回当前redis库所存储数据的大小 */ public Long dbSize() { Long dbSize = 0L; Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.dbSize(); jedisPool.returnResource(jedis); return dbSize; } catch (Exception e) { log.error(e); if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(e); } } /** * 关闭 Redis */ public void destory() { jedisPool.destroy(); } public JedisPool getJedisPool() { return jedisPool; } public void setJedisPool(JedisPool jedisPool) { this.jedisPool = jedisPool; } }JedisPool 管理类 ,对redis的java客户端jedis的封装
(7)com.securityframework.support.redis.RedisCacheManager
public class RedisCacheManager implements CacheManager { private static final Logger logger = LoggerFactory.getLogger(RedisCacheManager.class); // fast lookup by name map private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(); private JedisPoolManager redisManager; public <K, V> Cache<K, V> getCache(String name) throws CacheException { logger.debug("获取名称为: " + name + " 的RedisCache实例"); Cache c = caches.get(name); if (c == null) { c = new RedisCache<K, V>(redisManager); caches.put(name, c); } return c; } //setter和getter方法省略 }RedisCacheManager实现org.apache.shiro.cache.CacheManager接口,是shiro使用redis的缓存
(8)com.securityframework.support.redis.RedisSessionDAO
public class RedisSessionDAO extends AbstractSessionDAO { private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); /** * shiro-redis的session对象前缀 */ private final String SHIRO_REDIS_SESSION_PRE = "shiro_redis_session:"; /** * 存放uid的对象前缀 */ private final String SHIRO_SHESSIONID_PRE = "shiro_sessionid:"; /** * 存放uid 当前状态的前缀 */ private final String UID_PRE = "uid:"; /** * 存放用户权限的前缀 */ private final String PERMISSION_PRE ="permission:"; private JedisPoolManager redisManager; private long expire=180000; @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; } session.setTimeout(expire); Long redisExpire = expire/1000; int timeout = redisExpire.intValue(); JedisPool jedisPool = this.redisManager.getJedisPool(); Jedis jedis = null; try { jedis = jedisPool.getResource(); //保存用户会话 jedis.setex(this.getByteKey(this.SHIRO_REDIS_SESSION_PRE,session.getId()), timeout, SerializeUtils.serialize(session)); String uid = this.getUserId(session); if (null != uid && !"".equals(uid)){ //保存用户会话对应的UID jedis.setex(this.getByteKey(this.SHIRO_SHESSIONID_PRE,session.getId()),timeout, uid.getBytes()); //保存在线UID jedis.setex(this.getByteKey(this.UID_PRE,uid), timeout,"online".getBytes()); } jedisPool.returnResource(jedis); }catch(Exception ex){ if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(ex); } } @Override public void delete(Session session) { if (session == null || session.getId() == null) { logger.error("session or session id is null"); return; } JedisPool jedisPool = this.redisManager.getJedisPool(); Jedis jedis = null; try { jedis = jedisPool.getResource(); //删除用户会话 jedis.del(this.getByteKey(this.SHIRO_REDIS_SESSION_PRE,session.getId())); //获取缓存的用户会话对应的UID byte[] uid = jedis.get(this.getByteKey(this.SHIRO_SHESSIONID_PRE,session.getId())); //删除用户会话对应的UID jedis.del(this.getByteKey(this.SHIRO_SHESSIONID_PRE,session.getId())); //删除在线UID jedis.del(this.getByteKey(this.UID_PRE,new String(uid))); //删除用户缓存的权限 jedis.del(this.getByteKey(this.PERMISSION_PRE, new String(uid))); jedisPool.returnResource(jedis); }catch(Exception ex){ if (jedis != null) { jedisPool.returnBrokenResource(jedis); } throw new JedisException(ex); } } @Override public Collection<Session> getActiveSessions() { Set<Session> sessions = new HashSet<Session>(); Set<byte[]> keys = redisManager .keys(this.SHIRO_REDIS_SESSION_PRE + "*"); if (keys != null && keys.size() > 0) { for (byte[] key : keys) { Session s = (Session) SerializeUtils.deserialize(redisManager .get(key)); sessions.add(s); } } return sessions; } public boolean isOnLine(String uid){ Set<byte[]>keys = redisManager.keys(this.UID_PRE + uid); if (keys != null && keys.size() > 0){ return true; } return false; } @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; } logger.debug("#####Redis.SessionId=" + new String(getByteKey(this.SHIRO_REDIS_SESSION_PRE,sessionId))); Session s = (Session) SerializeUtils.deserialize(redisManager.get(this .getByteKey(this.SHIRO_REDIS_SESSION_PRE,sessionId))); return s; } /** * 获得byte[]型的key * * @param key * @return */ private byte[] getByteKey(String preKey,Serializable sessionId) { String key = preKey + sessionId; return key.getBytes(); } /** * 获取用户唯一标识 * @param session * @return */ private String getUserId(Session session){ SimplePrincipalCollection pricipal = (SimplePrincipalCollection)session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY"); if (null != pricipal){ Account account = ((Account) pricipal.getPrimaryPrincipal()); return account.getAccountId(); } return ""; } //setter和getter省略 }RedisSessionDAO继承org.apache.shiro.session.mgt.eis.AbstractSessionDAO,而AbstractSessionDAO是实现了org.apache.shiro.session.mgt.eis.SessionDAO接口的。
通过redis实现shiro的CacheManager接口,继承AbstractSessionDAO,实现shiro和redis的整合。
相关文章推荐
- shiro+redis+springMvc整合配置及说明
- shiro+redis+springMvc整合配置及说明
- SpringMVC+Shiro整合配置文件详解
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置
- SpringMVC+Shiro整合配置文件详解
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置
- 初步学习shiro+redis+springMVC的集成配置,做一下记录文档吧
- SpringMVC+Shiro整合配置文件详解
- windows环境下 springMVC+jdbc+redis整合配置
- 将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置
- SpringMVC+Shiro整合配置文件详解
- SpringMVC+Apache Shiro+JPA(hibernate)整合配置
- shiro开发,shiro的环境配置(基于spring+springMVC+redis)
- SpringMVC+Shiro整合配置文件详解
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置
- 将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学(一)整合配置
- SpringMVC+Shiro整合配置文件详解
- SpringMVC+Apache Shiro+JPA(hibernate)案例教学整合配置