您的位置:首页 > 数据库 > Redis

shiro+redis+springMvc整合配置及说明

2015-03-11 09:08 471 查看
技术背景: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>
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的整合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: