----知其然不知其所以然阶段---
总结:自定义redis继承shiro缓存所需要的对象的接口;
- shiro配置文件
@Configuration
public class ShiroConfiguration {
/**
* ShiroFilterFactoryBean 处理拦截资源文件问题。
* 注意:单独一个ShiroFilterFactoryBean配置是或报错的,以为在
* 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager Filter Chain定义说明
* 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过
* 3、部分过滤器可指定参数,如perms,roleso
*/
@Bean
public ShiroFilterFactoryBean shirFilter(
DefaultWebSecurityManager securityManager) {
System.out.println("shiro_config-shirFilter()....");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器.
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置静态资源允许访问
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
// filterChainDefinitionMap.put("/llse", "anon");
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login_token");
// 未授权界面;
// shiroFilterFactoryBean.setUnauthorizedUrl("/403");
//自定义
// Map<String, Filter> filters = new HashMap<String, Filter>();
// shiroFilterFactoryBean.setFilters(filters);
shiroFilterFactoryBean
.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 缓存数据 的配置ehcache-shiro.xml
* @return
*/
@Bean
public RedisCacheManager getEhCacheManager(JedisConnectionFactory jedisConnectionFactory) {
System.out.println("shiro_config-getEhCacheManager()....");
RedisCacheManager em = new RedisCacheManager(jedisConnectionFactory);
return em;
}
/**
* 开启shiro的设置文件代理
* 开启Controller中的shiro注解
* @return
*/
@Bean
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
System.out.println("shiro_config-getDefaultAdvisorAutoProxyCreator()....");
DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
daap.setProxyTargetClass(true);
return daap;
}
/**
* 配置org.apache.shiro.web.session.mgt.DefaultWebSessionManager
*
* @return
*/
@Bean
public DefaultWebSessionManager getDefaultWebSessionManager() {
System.out.println("shiro_config-getDefaultWebSessionManager()....");
DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
defaultWebSessionManager.setSessionDAO(getShiroRedisSessionDAO());
defaultWebSessionManager.setGlobalSessionTimeout(4200000);
defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
defaultWebSessionManager.setSessionIdCookieEnabled(true);
defaultWebSessionManager.setSessionIdCookie(getSimpleCookie());
return defaultWebSessionManager;
}
/**
* 配置org.apache.shiro.session.mgt.eis.MemorySessionDAO
*
* @return
*/
@Bean
public ShiroRedisSessionDAO getShiroRedisSessionDAO() {
System.out.println("shiro_config-getMemorySessionDAO()....");
ShiroRedisSessionDAO shiroRedisSessionDAO = new ShiroRedisSessionDAO();
return shiroRedisSessionDAO;
}
/* @Bean
public RedisTemplate getRedisTemplate(){
System.out.println("getRedisTemplate....");
return new RedisTemplate();
}*/
@Bean
public JavaUuidSessionIdGenerator javaUuidSessionIdGenerator() {
System.out.println("shiro_config_javaUuidSessionIdGenerator()....");
return new JavaUuidSessionIdGenerator();
}
/**
* session自定义cookie名
*
* @return
*/
@Bean
public SimpleCookie getSimpleCookie() {
System.out.println("shiro_config_getSimpleCookie()....");
SimpleCookie simpleCookie = new SimpleCookie();
simpleCookie.setName("security.session.id");
simpleCookie.setPath("/");
return simpleCookie;
}
@Bean
public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(
UserRealm userRealm,JedisConnectionFactory jedisConnectionFactory) {
System.out.println("shiro_config_getDefaultWebSecurityManager()....");
DefaultWebSecurityManager dwsm = new DefaultWebSecurityManager();
dwsm.setRealm(userRealm);
// <!-- 用户授权/认证信息Cache, 采用EhCache 缓存 -->
dwsm.setCacheManager(getEhCacheManager(jedisConnectionFactory));
dwsm.setSessionManager(getDefaultWebSessionManager());
return dwsm;
}
@Bean
public UserRealm userRealm(RedisCacheManager cacheManager) {
System.out.println("shiro_config_userRealm()....");
UserRealm userRealm = new UserRealm();
userRealm.setCachingEnabled(true);
userRealm.setCacheManager(cacheManager);
//启用身份验证缓存
userRealm.setAuthenticationCachingEnabled(true);
//启用授权缓存,
userRealm.setAuthorizationCachingEnabled(true);
return userRealm;
}
/**
* 开启shrio注解支持
*
* @param userRealm
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor(
UserRealm userRealm,JedisConnectionFactory jedisConnectionFactory) {
System.out.println("shiro_getAuthorizationAttributeSourceAdvisor()....");
AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor();
aasa.setSecurityManager(getDefaultWebSecurityManager(userRealm,jedisConnectionFactory));
return aasa;
}
}
- 实现CacheManager.java接口
public class RedisCacheManager implements CacheManager,Destroyable{
private JedisConnectionFactory jedisConnectionFactory;
public RedisCacheManager(JedisConnectionFactory jedisConnectionFactory) {
this.jedisConnectionFactory = jedisConnectionFactory;
}
@Override
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
RedisCache<K,V> redisCache = new RedisCache<K,V>(name,jedisConnectionFactory);
return redisCache;
}
@Override
public void destroy() throws Exception {
// TODO Auto-generated method stub
}
}
- 实现Cache.java接口
public class RedisCache<K, V> implements Cache<K, V> {
@Value("${shiro.session.outTime}") //不知道为什么没效果
private Long sessionOutTime = 60000L;
@Value("${shiro.realm.outTime}")
private Long realmOutTime = 30000L;
private Long time;
private String keyPrefix = "redis.shiro.cache.key_";
/**
* key前缀
*/
private static final String REDIS_SHIRO_CACHE_KEY_PREFIX = "redis.shiro.cache_";
/**
* cache name
*/
private String name;
/**
* jedis 连接工厂
*/
private JedisConnectionFactory jedisConnectionFactory;
/**
* 序列化工具
* 使用自定义序列化工具不只为什么出现问题
*/
private RedisSerializer serializer = new JdkSerializationRedisSerializer();
public RedisCache(String name, JedisConnectionFactory jedisConnectionFactory) {
this.jedisConnectionFactory = jedisConnectionFactory;
this.name = name;
keyPrefix += name;
}
public String getKeyPrefix() {
return keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
}
@Override
public V get(K key) throws CacheException {
V result = null;
RedisConnection redisConnection = null;
try {
redisConnection = jedisConnectionFactory.getConnection();
result = (V) serializer.deserialize(redisConnection.get(serializer.serialize(generateKey(key))));
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
public V put(K key, V value) throws CacheException {
V result = null;
RedisConnection redisConnection = null;
if(key.toString().contains("session")){
time = sessionOutTime;
}else{
time = realmOutTime;
}
try {
redisConnection = jedisConnectionFactory.getConnection();
result = (V) serializer.deserialize(redisConnection.get(serializer.serialize(generateKey(key))));
String str = new String(serializer.serialize(generateKey(key)));
redisConnection.pSetEx(serializer.serialize(generateKey(key)),time ,serializer.serialize(value));
redisConnection.lPush(serializer.serialize(keyPrefix),serializer.serialize(generateKey(key)));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != redisConnection) {
redisConnection.close();
}
}
return result;
}
@SuppressWarnings("unchecked")
@Override
public V remove(K key) throws CacheException {
RedisConnection redisConnection = null;
V result = null;
try {
redisConnection = jedisConnectionFactory.getConnection();
result = (V) serializer.deserialize(redisConnection.get(serializer.serialize(generateKey(key))));
redisConnection.expireAt(serializer.serialize(generateKey(key)), 0);
redisConnection.lRem(serializer.serialize(keyPrefix), 0, serializer.serialize(key));
} catch (Exception e) {
} finally {
if (null != redisConnection) {
redisConnection.close();
}
}
return result;
}
@Override
public void clear() throws CacheException {
RedisConnection redisConnection = null;
try {
redisConnection = jedisConnectionFactory.getConnection();
Long length = redisConnection.lLen(serializer.serialize(keyPrefix));
if (0 == length) {
return;
}
List<byte[]> keyList = redisConnection.lRange(serializer.serialize(keyPrefix), 0, length - 1);
for (byte[] key : keyList) {
redisConnection.expireAt(key, 0);
}
redisConnection.expireAt(serializer.serialize(keyPrefix), 0);
keyList.clear();
} catch (Exception e) {
} finally {
if (null != redisConnection) {
redisConnection.close();
}
}
}
@Override
public int size() {
RedisConnection redisConnection = null;
int length = 0;
try {
redisConnection = jedisConnectionFactory.getConnection();
length = Math.toIntExact(redisConnection.lLen(serializer.serialize(keyPrefix)));
} catch (Exception e) {
// LOGGER.error("shiro redis cache size exception.", e);
} finally {
if (null != redisConnection) {
redisConnection.close();
}
}
return length;
}
@Override
public Set keys() {
RedisConnection redisConnection = null;
Set resultSet = null;
try {
redisConnection = jedisConnectionFactory.getConnection();
Long length = redisConnection.lLen(serializer.serialize(keyPrefix));
if (0 == length) {
return resultSet;
}
List<byte[]> keyList = redisConnection.lRange(serializer.serialize(keyPrefix), 0, length - 1);
resultSet = keyList.stream().map(bytes -> serializer.deserialize(bytes)).collect(Collectors.toSet());
} catch (Exception e) {
} finally {
if (null != redisConnection) {
redisConnection.close();
}
}
return resultSet;
}
@Override
public Collection values() {
return null;
}
/**
* 重组key 区别其他使用环境的key
*
* @param key
* @return
*/
private String generateKey(K key) {
String ste = REDIS_SHIRO_CACHE_KEY_PREFIX + name + "_" + key;
return REDIS_SHIRO_CACHE_KEY_PREFIX + name + "_" + key;
}
}
- session缓存
/** * ShiroRedisCacheSessionDAO */ public class ShiroRedisSessionDAO extends CachingSessionDAO { @Override protected void doUpdate(Session session) { this.getCacheManager().getCache(this.getClass().getName()).put(session.getId(), session); } @Override protected void doDelete(Session session) { this.getCacheManager().getCache(this.getClass().getName()).remove(session.getId()); } @Override protected Serializable doCreate(Session session) { Serializable sessionId = this.generateSessionId(session); this.assignSessionId(session, sessionId); this.getCacheManager().getCache(this.getClass().getName()).put(session.getId(), session); return sessionId; } @Override protected Session doReadSession(Serializable sessionId) { return (Session) this.getCacheManager().getCache(this.getClass().getName()).get(sessionId); } }