基于redis缓存的session共享


结合上面的 MSM 思想,由 redis负责 session 数据的存储,而我们自己实现的 session manager 将负责 session 生命周期的管理。


redission具体使用_redission具体使用


   此架构存在着当redis master故障时, 虽然可以有一到多个备用slave,但是redis不会主动的进行master切换,这时session服务中断。


      为了做到redis的高可用,引入了zookper或者haproxy或者keepalived来解决redis master slave的切换问题。即:

redission具体使用_redis_02


  此体系结构中, redis master出现故障时, 通过haproxy设置redis slave为临时master, redis master重新恢复后,

 再切换回去. 此方案中, redis-master 与redis-slave 是双向同步的, 解决目前redis单点问题. 这样保证了session信息

在redis中的高可用。

 

实现此方案:

nginx        1   192.168.1.102
tomcat1    1  
tomcat2    1
redis-master   1 
redis-slave      1
slave1     1
slave2     1
haproxy vip  1

Apache Shiro集群要解决2个问题,一个是session的共享问题,一个是授权信息的cache共享问题。从DefaultWebSecurityManager入手看源码

发现其父类DefaultSessionManager中有sessionDAO属性,这个属性是真正实现了session储存的类,这个就是我们自己实现的redis session的储存类。


RedisSessionDAO.java
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.util.SerializationUtils;


 import java.io.Serializable;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;

 public class RedisSessionDAO extends AbstractSessionDAO {
     private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);
     /**
      * shiro-redis的session对象前缀
      */
     private RedisManager redisManager;


     /**
      * The Redis key prefix for the sessions
      */
     private String keyPrefix = "shiro_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{
         System.out.println("----saveSession---"+session.getId());
         if(session == null || session.getId() == null){
             logger.error("session or session id is null");
             return;
         }


         byte[] key = getByteKey(session.getId());
         byte[] value = SerializationUtils.serialize(session);
        // session.setTimeout(redisManager.getExpire()*1000);
      this.redisManager.set(key, value, Integer.parseInt(session.getTimeout()+""));

     }


     @Override
     public void delete(Session session) {
         if(session == null || session.getId() == null){
             logger.error("session or session id is null");
             return;
         }
         redisManager.del(this.getByteKey(session.getId()));


     }


     @Override
     public Collection<Session> getActiveSessions() {
         Set<Session> sessions = new HashSet<Session>();


         Set<byte[]> keys = redisManager.keys(this.keyPrefix + "*");
         if(keys != null && keys.size()>0){
             for(byte[] key:keys){
                 Session s = (Session)SerializationUtils.deserialize(redisManager.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)SerializationUtils.deserialize(redisManager.get(this.getByteKey(sessionId)));
         return s;
     }


     /**
      * 获得byte[]型的key
      * @param sessionId
      * @return
      */
     private byte[] getByteKey(Serializable sessionId){
         String preKey = this.keyPrefix + sessionId;
         return preKey.getBytes();
     }


     public RedisManager getRedisManager() {
         return redisManager;
     }


     public void setRedisManager(RedisManager redisManager) {
         this.redisManager = redisManager;


         /**
          * 初始化redisManager
          */
         this.redisManager.init();
     }


     /**
      * 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;
     }
 }
 RedisManager.java 
 
 
 import org.slf4j.Logger; 
 
 import org.slf4j.LoggerFactory; 
 
 import redis.clients.jedis.Jedis; 
 
 import redis.clients.jedis.JedisPool; 
 
 import redis.clients.jedis.JedisPoolConfig; 
 


 import java.util.Set; 
 
 public class RedisManager { 
 
     private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); 
 


     private String host; 
 


     private int port; 
 


     // 0 - never expire 
 
     private int expire = 0; 
 


     private static JedisPool jedisPool = null; 
 


     public RedisManager() { 
 
     } 
 




     /** 
 
      * 初始化方法 
 
      */ 
 
     public void init(){ 
 
         if(null == host || 0 == port){ 
 
             logger.error("请初始化redis配置文件!"); 
 
             throw new NullPointerException("找不到redis配置"); 
 
         } 
 
         if(jedisPool == null){ 
 
             //jedisPool = JedisUtil.getJedisPool(); 
 
             jedisPool = new JedisPool(new JedisPoolConfig(), host, port); 
 


         } 
 
     } 
 


     /** 
 
      * get value from redis 
 
      * @param key 
 
      * @return 
 
      */ 
 
     public byte[] get(byte[] key) { 
 
         byte[] value = null; 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             value = jedis.get(key); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return value; 
 
     } 
 
     /** 
 
      * get value from redis 
 
      * @param key 
 
      * @return 
 
      */ 
 
     public String get(String key) { 
 
         String value=null; 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             value = jedis.get(key); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return value; 
 
     } 
 


     /** 
 
      * set 
 
      * @param key 
 
      * @param value 
 
      * @return 
 
      */ 
 
     public byte[] set(byte[] key, byte[] value) { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.set(key, value); 
 
             if (this.expire != 0) { 
 
                 jedis.expire(key, this.expire); 
 
             } 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return value; 
 
     } 
 
     /** 
 
      * set 
 
      * @param key 
 
      * @param value 
 
      * @return 
 
      */ 
 
     public String set(String key,String value) { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.set(key, value); 
 
             if (this.expire != 0) { 
 
                 jedis.expire(key, this.expire); 
 
             } 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return value; 
 
     } 
 


     /** 
 
      * set 
 
      * @param key 
 
      * @param value 
 
      * @param expire 
 
      * @return 
 
      */ 
 
     public byte[] set(byte[] key, byte[] value, int expire) { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.set(key, value); 
 
             if (expire != 0) { 
 
                 jedis.expire(key, expire); 
 
             } 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return value; 
 
     } 
 
     /** 
 
      * set 
 
      * @param key 
 
      * @param value 
 
      * @param expire 
 
      * @return 
 
      */ 
 
     public String set(String key,String value, int expire) { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.set(key, value); 
 
             if (expire != 0) { 
 
                 jedis.expire(key, expire); 
 
             } 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return value; 
 
     } 
 


     /** 
 
      * del 
 
      * @param key 
 
      */ 
 
     public void del(byte[] key) { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.del(key); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
     } 
 
     /** 
 
      * del 
 
      * @param key 
 
      */ 
 
     public void del(String key) { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.del(key); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
     } 
 


     /** 
 
      * flush 
 
      */ 
 
     public void flushDB() { 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             jedis.flushDB(); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
     } 
 


     /** 
 
      * size 
 
      */ 
 
     public Long dbSize() { 
 
         Long dbSize = 0L; 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             dbSize = jedis.dbSize(); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return dbSize; 
 
     } 
 


     /** 
 
      * keys 
 
      * @param pattern 
 
      * @return 
 
      */ 
 
     public Set<byte[]> keys(String pattern) { 
 
         Set<byte[]> keys = null; 
 
         Jedis jedis = jedisPool.getResource(); 
 
         try { 
 
             keys = jedis.keys(pattern.getBytes()); 
 
         } finally { 
 
             jedisPool.returnResource(jedis); 
 
         } 
 
         return keys; 
 
     } 
 


     public String getHost() { 
 
         return host; 
 
     } 
 


     public void setHost(String host) { 
 
         this.host = host; 
 
     } 
 


     public int getPort() { 
 
         return port; 
 
     } 
 


     public void setPort(int port) { 
 
         this.port = port; 
 
     } 
 


     public int getExpire() { 
 
         return expire; 
 
     } 
 


     public void setExpire(int expire) { 
 
         this.expire = expire; 
 
     } 
 


     public void destroy(){ 
 
         jedisPool.destroy(); 
 
     } 
 
 }



RedisCacheManager.java

import org.apache.shiro.ShiroException;
 import org.apache.shiro.cache.Cache;
 import org.apache.shiro.cache.CacheException;
 import org.apache.shiro.cache.CacheManager;
 import org.apache.shiro.cache.MapCache;
 import org.apache.shiro.util.Destroyable;
 import org.apache.shiro.util.Initializable;
 import org.apache.shiro.util.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import redis.clients.jedis.JedisPoolConfig;
 import redis.clients.jedis.JedisShardInfo;
 import redis.clients.jedis.ShardedJedisPool;


 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;




 public class RedisCacheManager implements CacheManager, Destroyable {
     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 RedisManager redisManager;


     /**
      * The Redis key prefix for caches
      */
     private String keyPrefix = "shiro_redis_cache:";


     /**
      * 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;
     }


     @Override
     public <K, V> Cache<K, V> getCache(String name) throws CacheException {
         logger.debug("获取名称为: " + name + " 的RedisCache实例");


         Cache c = caches.get(name);


         if (c == null) {


             // initialize the Redis manager instance
             redisManager.init();


             // create a new cache instance
             c = new RedisCache<K, V>(redisManager, keyPrefix);


             // add it to the cache collection
             caches.put(name, c);
         }
         return c;
     }


     public RedisManager getRedisManager() {
         return redisManager;
     }


     public void setRedisManager(RedisManager redisManager) {
         this.redisManager = redisManager;
     }


     @Override
     public void destroy() throws Exception {
         this.redisManager.destroy();
     }
 }

 
 RedisCache.javapackage com.zte.alm.cs.ui.shiro.redis; 
 
 package com.zte.alm.cs.ui.shiro.redis; 
 


 import org.apache.shiro.cache.Cache; 
 
 import org.apache.shiro.cache.CacheException; 
 
 import org.apache.shiro.subject.PrincipalCollection; 
 
 import org.slf4j.Logger; 
 
 import org.slf4j.LoggerFactory; 
 
 import org.springframework.util.CollectionUtils; 
 
 import org.springframework.util.SerializationUtils; 
 
 import redis.clients.jedis.Jedis; 
 
 import redis.clients.jedis.ShardedJedis; 
 
 import redis.clients.jedis.ShardedJedisPool; 
 


 import java.util.*; 
 


 public class RedisCache<K, V> implements Cache<K, V> { 
 
     private Logger logger = LoggerFactory.getLogger(this.getClass()); 
 


     /** 
 
      * The wrapped Jedis instance. 
 
      */ 
 
     private RedisManager cache; 
 


     /** 
 
      * The Redis key prefix for the sessions 
 
      */ 
 
     private String keyPrefix = "shiro_session:"; 
 


     /** 
 
      * 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; 
 
     } 
 


     /** 
 
      * 通过一个JedisManager实例构造RedisCache 
 
      */ 
 
     public RedisCache(RedisManager cache) { 
 
         if (cache == null) { 
 
             throw new IllegalArgumentException("Cache argument cannot be null."); 
 
         } 
 
         this.cache = cache; 
 
     } 
 


     /** 
 
      * Constructs a cache instance with the specified 
 
      * Redis manager and using a custom key prefix. 
 
      * @param cache The cache manager instance 
 
      * @param prefix The Redis key prefix 
 
      */ 
 
     public RedisCache(RedisManager cache, String prefix) { 
 


         this(cache); 
 


         // set the prefix 
 
         this.keyPrefix = prefix; 
 
     } 
 


     /** 
 
      * 获得byte[]型的key 
 
      * @param key 
 
      * @return 
 
      */ 
 
     private byte[] getByteKey(K key) { 
 
         if (key instanceof String) { 
 
             String preKey = this.keyPrefix + key; 
 
             return preKey.getBytes(); 
 
         } else if(key instanceof PrincipalCollection){ 
 
             String preKey = this.keyPrefix + key.toString(); 
 
             return preKey.getBytes(); 
 
         }else{ 
 
             return SerializationUtils.serialize(key); 
 
         } 
 
     } 
 


     @Override 
 
     public V get(K key) throws CacheException { 
 
         logger.debug("根据key从Redis中获取对象 key [" + key + "]"); 
 
         try { 
 
             if (key == null) { 
 
                 return null; 
 
             } else { 
 
                 byte[] rawValue = cache.get(getByteKey(key)); 
 
                 @SuppressWarnings("unchecked") 
 
                 V value = (V) SerializationUtils.deserialize(rawValue); 
 
                 return value; 
 
             } 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 


     } 
 
     public String getStr(String key) throws CacheException { 
 
         logger.debug("根据key从Redis中获取对象 key [" + key + "]"); 
 
         try { 
 
             if (key == null) { 
 
                 return null; 
 
             } else { 
 
                 return cache.get(key); 
 
             } 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 


     } 
 


     @Override 
 
     public V put(K key, V value) throws CacheException { 
 
         logger.debug("根据key从存储 key [" + key + "]"); 
 
         try { 
 
             cache.set(getByteKey(key), SerializationUtils.serialize(value)); 
 
             return value; 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     public String putStr(String key, String value) throws CacheException { 
 
         logger.debug("根据key从存储 key [" + key + "]"); 
 
         try { 
 
             cache.set(key, value); 
 
             return value; 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     public String put(String key,String value, int expire) throws CacheException { 
 
         logger.debug("根据key从存储 key [" + key + "]"); 
 
         try { 
 
             cache.set(key, value, expire); 
 
             return value; 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     public String removeString(String key) throws CacheException { 
 
         logger.debug("从redis中删除 key [" + key + "]"); 
 
         try { 
 
             String previous = cache.get(key); 
 
             cache.del(key); 
 
             return previous; 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     @Override 
 
     public V remove(K key) throws CacheException { 
 
         logger.debug("从redis中删除 key [" + key + "]"); 
 
         try { 
 
             V previous = get(key); 
 
             cache.del(getByteKey(key)); 
 
             return previous; 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     @Override 
 
     public void clear() throws CacheException { 
 
         logger.debug("从redis中删除所有元素"); 
 
         try { 
 
             cache.flushDB(); 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     @Override 
 
     public int size() { 
 
         try { 
 
             Long longSize = new Long(cache.dbSize()); 
 
             return longSize.intValue(); 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     @SuppressWarnings("unchecked") 
 
     @Override 
 
     public Set<K> keys() { 
 
         try { 
 
             Set<byte[]> keys = cache.keys(this.keyPrefix + "*"); 
 
             if (CollectionUtils.isEmpty(keys)) { 
 
                 return Collections.emptySet(); 
 
             } else { 
 
                 Set<K> newKeys = new HashSet<K>(); 
 
                 for (byte[] key : keys) { 
 
                     newKeys.add((K) key); 
 
                 } 
 
                 return newKeys; 
 
             } 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


     @Override 
 
     public Collection<V> values() { 
 
         try { 
 
             Set<byte[]> keys = cache.keys(this.keyPrefix + "*"); 
 
             if (!CollectionUtils.isEmpty(keys)) { 
 
                 List<V> values = new ArrayList<V>(keys.size()); 
 
                 for (byte[] key : keys) { 
 
                     @SuppressWarnings("unchecked") V value = get((K) key); 
 
                     if (value != null) { 
 
                         values.add(value); 
 
                     } 
 
                 } 
 
                 return Collections.unmodifiableList(values); 
 
             } else { 
 
                 return Collections.emptyList(); 
 
             } 
 
         } catch (Throwable t) { 
 
             throw new CacheException(t); 
 
         } 
 
     } 
 


 }

ShiroRealm.java




import java.util.ArrayList; 
 
 import java.util.Collection; 
 
 import java.util.HashMap; 
 
 import java.util.HashSet; 
 
 import java.util.List; 
 
 import java.util.Map; 
 


 import javax.annotation.Resource; 
 


 import org.apache.shiro.authc.AuthenticationException; 
 
 import org.apache.shiro.authc.AuthenticationInfo; 
 
 import org.apache.shiro.authc.AuthenticationToken; 
 
 import org.apache.shiro.authc.SimpleAuthenticationInfo; 
 
 import org.apache.shiro.authz.AuthorizationInfo; 
 
 import org.apache.shiro.authz.SimpleAuthorizationInfo; 
 
 import org.apache.shiro.realm.AuthorizingRealm; 
 
 import org.apache.shiro.subject.PrincipalCollection; 
 
 import org.apache.shiro.util.ByteSource; 
 
 import org.slf4j.Logger; 
 
 import org.slf4j.LoggerFactory; 
 
 import org.springframework.stereotype.Service; 
 


 import com.zte.alm.cs.persist.entity.sys.SysUser; 
 
 import com.zte.alm.cs.service.sys.ISysGroupService; 
 
 import com.zte.alm.cs.service.sys.ISysOrgRoleService; 
 
 import com.zte.alm.cs.service.sys.ISysOrgService; 
 
 import com.zte.alm.cs.service.sys.ISysPermissionResourceService; 
 
 import com.zte.alm.cs.service.sys.ISysUserService; 
 


 public class ShiroRealm extends AuthorizingRealm { 
 
private static final Logger log = LoggerFactory.getLogger(ShiroRealm.class); 
 


 
 

 //清空 
 
protected void doClearCache(PrincipalCollection principals) { 
 
super.doClearCache(principals); 
 
this.clearCachedAuthorizationInfo(principals); 
 
} 
 

  //修改key的值 
 
public Object getAuthorizationCacheKey(PrincipalCollection principals){ 
 
Collection<?> collection = principals.fromRealm(getName()); 
 
if (collection == null || collection.isEmpty()) { 
 
return null; 
 
} 
 


ShiroUser shiroUser = (ShiroUser) collection.iterator().next(); 
 
return shiroUser.getLoginName(); 
 
} 
 
 
 
applicationContext-shiro.xml 
 
 <?xml version="1.0" encoding="UTF-8"?> 
 
 <beans xmlns="http://www.springframework.org/schema/beans" 
 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" 
 
default-lazy-init="true"> 
 


<description>Shiro安全配置</description> 
 


<!-- 凭证匹配器 --> 
 
<bean id="credentialsMatcher" class="com.test.shiro.CredentialsMatcher"> 
 


</bean> 
 
<!-- Shiro's main business-tier object for web-enabled applications --> 
 
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
 
<property name="sessionManager" ref="defaultWebSessionManager" /> 
 
<property name="realm" ref="almShiroRealm" /> 
 
<!-- <property name="cacheManager" ref="shiroEhcacheManager" /> --> 
 
<property name="cacheManager" ref="redisCacheManager" /> 
 
</bean> 
 
<bean id="defaultWebSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> 
 
<!-- 相隔多久检查一次session的有效性 --> 
 
<property name="sessionValidationInterval" value="1800000"/> 
 
<!-- session 有效时间为半小时 (毫秒单位)--> 
 
<property name="globalSessionTimeout" value="1800000"/> 
 


<!-- 是否在会话过期后会调用SessionDAO的delete方法删除会话 默认true --> 
 
<property name="deleteInvalidSessions" value="true" /> 
 


<property name="sessionDAO" ref="redisShiroSessionDAO"/> 
 


</bean> 
 

<!-- 項目自定义的Realm --> 
 
<bean id="almShiroRealm" class="com.test.shiro.ShiroRealm"> 
 
<property name="credentialsMatcher" ref="credentialsMatcher" /> 
 
</bean> 
 


<!-- Shiro Filter --> 
 
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
 
<property name="securityManager" ref="securityManager" /> 
 
<property name="loginUrl" value="/login" /> 
 
<property name="successUrl" value="/login/index" /> 
 
<property name="filters"> 
 
<map> 
 
<!-- 是否启用验证码检验 --> 
 
<entry key="authc" value-ref="CaptchaFormAuthenticationFilter" /> 
 
<entry key="user" value-ref="AlmUserFilter" /> 
 
</map> 
 
</property> 
 
<property name="filterChainDefinitions"> 
 
<value> 
 
/js/** = anon 
 
/css/**=anon 
 
/img/**=anon 
 
/font/**=anon 
 
/mail/**=anon 
 
/login =authc 
 
/logout = logout 
 
/** = user 
 
</value> 
 
</property> 
 
</bean> 
 


<!-- 用户授权信息Cache, 采用EhCache --> 
 
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> 
 
<property name="cacheManagerConfigFile" value="classpath:conf/ehcache/ehcache-shiro.xml" /> 
 
</bean> 
 
<bean id="redisShiroSessionDAO" class="com.test.shiro.redis.RedisSessionDAO"> 
 
<property name="redisManager" ref="redisManager" /> 
 
</bean> 
 
<bean id="redisCacheManager" class="com.test.shiro.redis.RedisCacheManager"><!-- 自定义cacheManager --> 
 
<property name="redisManager" ref="redisManager" /> 
 
</bean> 
 
<bean id="redisManager" class="com.test.shiro.redis.RedisManager"> 
 
<property name="host" value="127.0.0.1" /> 
 
<property name="port" value="6379" /> 
 
</bean> 
 


<bean id="CaptchaFormAuthenticationFilter" class="com.test.shiro.CaptchaFormAuthenticationFilter" /> 
 
<bean id="AlmUserFilter" class="com.test.shiro.AlmUserFilter" /> 
 


<!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> 
 
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> 

 </beans> 
 

/** 
 
* 权限 
 
*/ 
 
@Override 
 
protected AuthorizationInfo doGetAuthorizationInfo( 
 
PrincipalCollection principals) { 
 
log.info("--doGetAuthorizationInfo--"); 
 
// TODO Auto-generated method stub 
 
Collection<?> collection = principals.fromRealm(getName()); 
 
if (collection == null || collection.isEmpty()) { 
 
return null; 
 
} 
 


ShiroUser shiroUser = (ShiroUser) collection.iterator().next(); 
 
return newAuthorizationInfo(shiroUser); 
 
} 
 
private SimpleAuthorizationInfo newAuthorizationInfo(ShiroUser shiroUser) { 
 
 
} 
 

/** 
 
* 用户认证 
 
*/ 
 
@Override 
 
protected AuthenticationInfo doGetAuthenticationInfo( 
 
AuthenticationToken paramAuthenticationToken) 
 
throws AuthenticationException { 
 
} 
 
 }



补充:发现在realm的权限中设置的shiroUser信息没有生效,处理方式,重新设置session的属性值


Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
String RUN_AS_PRINCIPALS_SESSION_KEY = "org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY";
PrincipalCollection  principals =  new SimplePrincipalCollection(shiroUser,this.getName());
session.setAttribute(RUN_AS_PRINCIPALS_SESSION_KEY, principals);