转自: http://blog.csdn.net/siqilou/article/details/44194165
技术背景:shiro安全框架,redis作缓存,再整合spring。
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>
- <!--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配置-->
<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方法省略
- **/
- }
(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();
- }
- }
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;
- }
- }
(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方法省略
- }
(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省略
- }
通过redis实现shiro的CacheManager接口,继承AbstractSessionDAO,实现shiro和redis的整合。