shiro-redis整合demo

----知其然不知其所以然阶段--- 

总结:自定义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);
        }
    }

     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值