Shiro功能应用--Shiro集成RedisTemplate(SDR)
Posted 做猪呢,最重要的是开森啦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shiro功能应用--Shiro集成RedisTemplate(SDR)相关的知识,希望对你有一定的参考价值。
文章目录
上一篇文章Shiro功能应用(七)–Shiro集成Redis缓存(shiro-redis3.1.0)中提到,继承shiro-redis,授权的User实体类要有AuthCacheKey或者Id属性,这有一定局限性,本文在上一篇文章代码基础上,修改成集成SDR(spring-boot-starter-data-redis依赖)
代码实现:
代码地址:
https://github.com/OooooOz/SpringBoot-Shiro
自定义缓存处理器
继承CacheManager,重写getCache方法,方法返回自定义缓存类(实现cache接口,重写get、remove等方法)。
hashKey()方法对获取缓存做兼容,shiro缓存中获取认证if的key是username,而缓存获取权限info的key是user对象,所以做个区分。
//redis缓存实现类
package com.demo.config;
import java.util.Collection;
import java.util.Set;
import javax.annotation.Resource;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import com.demo.entity.User;
@Component
public class RedisCacheManager implements CacheManager
private String cacheKeyPrefix = "shiro:";
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException
return new ShiroRedisCache<K,V>(cacheKeyPrefix+name);
/**
* 为shiro量身定做的一个redis cache,为Authorization cache做了特别优化
*/
public class ShiroRedisCache<K, V> implements Cache<K, V>
private String cacheKey;
public ShiroRedisCache(String cacheKey)
this.cacheKey=cacheKey;
@Override
public V get(K key) throws CacheException
BoundHashOperations<String,K,V> hash = redisTemplate.boundHashOps(cacheKey);
Object k=hashKey(key);
V v = hash.get(k);
return v;
@Override
public V put(K key, V value) throws CacheException
BoundHashOperations<String,K,V> hash = redisTemplate.boundHashOps(cacheKey);
Object k=hashKey(key);
hash.put((K)k, value);
return value;
@Override
public V remove(K key) throws CacheException
BoundHashOperations<String,K,V> hash = redisTemplate.boundHashOps(cacheKey);
Object k=hashKey(key);
V value=hash.get(k);
hash.delete(k);
return value;
@Override
public void clear() throws CacheException
redisTemplate.delete(cacheKey);
@Override
public int size()
BoundHashOperations<String,K,V> hash = redisTemplate.boundHashOps(cacheKey);
return hash.size().intValue();
@Override
public Set<K> keys()
BoundHashOperations<String,K,V> hash = redisTemplate.boundHashOps(cacheKey);
return hash.keys();
@Override
public Collection<V> values()
BoundHashOperations<String,K,V> hash = redisTemplate.boundHashOps(cacheKey);
return hash.values();
protected Object hashKey(K key)
//此处很重要,如果key是登录凭证,那么这是访问用户的授权缓存;将登录凭证转为user对象,
//返回user的name属性做为hash key,否则会以user对象做为hash key,这样就不好清除指定用户的缓存了
if(key instanceof PrincipalCollection)
PrincipalCollection pc=(PrincipalCollection) key;
User user =(User)pc.getPrimaryPrincipal();
return user.getUserName();
else if (key instanceof User)
User user =(User) key;
return user.getUserName();
return key;
ShiroConfig的注入自定义缓存管理器*以及redisTemplate
/**
* 注入redisTemplate工具
* */
@Bean
public StringRedisTemplate redisTemplate(JedisConnectionFactory jedisConnectionFactory)
StringRedisTemplate redisTemplate = new StringRedisTemplate(jedisConnectionFactory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer); //键值序列化方式
redisTemplate.setValueSerializer(jdkSerializationRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer); //绑定hash的序列化方式
redisTemplate.setHashValueSerializer(jdkSerializationRedisSerializer);
// redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
/**
* Jedis连接工厂,Springboot2.0以上采用redisStandaloneConfiguration
* */
@Bean
public JedisConnectionFactory jedisConnectionFactory(RedisStandaloneConfiguration redisStandaloneConfiguration)
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration);
return jedisConnectionFactory;
//JedisConnectionFactory注入的redis配置
@Bean
public RedisStandaloneConfiguration redisStandaloneConfiguration()
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName("192.168.2.104");
redisStandaloneConfiguration.setPort(6379);
//redisStandaloneConfiguration.setPassword(RedisPassword);
return redisStandaloneConfiguration;
/**
* 自定义封装的redis缓存操作类
* */
@Bean("redisCacheManager")
public RedisCacheManager redisCacheManager()
RedisCacheManager redisCacheManager = new RedisCacheManager();
return redisCacheManager;
KickOut过滤器修改:
之前EHCache缓存时,队列可以先放缓存,再往缓存的队列push值。险种Redis做缓存,需要先将sessionId值放入队列,队列再放入缓存:
功能测试:
打开两个浏览器登录,会有一个被踢出来,集成完毕。从RDM里可以看到redis缓存。
以上是关于Shiro功能应用--Shiro集成RedisTemplate(SDR)的主要内容,如果未能解决你的问题,请参考以下文章