springboot1.5.3+shiro1.3.2+redis單節點及叢集整合
阿新 • • 發佈:2018-11-13
專案要求直接在配置檔案中可切換redis單節點和叢集模式,以前依賴shiro-redis開源專案,雖然可切換但有點麻煩,研究藉助spring-data-redis直接整合。
一、配置檔案
spring:
redis:
database: 0
host: redis
password:
port: 6379
timeout: 60000
#cluster:
#nodes: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003,127.0.0.1:7004,127.0.0.1:7005
pool:
max-active: 80
max-idle: 8
max-wait: -1
min-idle: 0
上面是單節點配置,叢集去掉註釋cluster,及nodes.如下:
spring:
redis:
database: 0
# host: redis
password:
# port: 6379
timeout: 60000
cluster:
nodes: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002,127.0.0.1:7003, 127.0.0.1:7004,127.0.0.1:7005
pool:
max-active: 80
max-idle: 8
max-wait: -1
min-idle: 0
上述host及port也可不註釋,優先使用叢集模式。
二、shiro配置
@Configuration
public class ShiroConfig {
@Autowired
private RedisTemplate redisTemplate;
/**
* 自己實現
* @title systemCredentilsMatch
* @description 密碼驗證器
* @param
* @return SimpleCredentialsMatcher 返回型別
* @throws
*/
@Bean
public SimpleCredentialsMatcher systemCredentilsMatch(){
return new SystemCredentilsMatch();
}
/**
* 自己的realm
* @title systemShiroRealms
* @description 身份認證以及授權
* @param
* @return SystemShiroRealms 返回型別
* @throws
*/
@Bean
public SystemShiroRealms systemShiroRealms(){
SystemShiroRealms systemShiroRealms = new SystemShiroRealms();
systemShiroRealms.setCredentialsMatcher(systemCredentilsMatch());
return systemShiroRealms;
}
/**
*
* @title systemSessionManager
* @description session管理器設定
* @param
* @return SystemSessionManager 返回型別
* @throws
*/
@Bean
public SystemSessionManager systemSessionManager(){
SystemSessionManager systemSessionManager = new SystemSessionManager();
systemSessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
return systemSessionManager;
}
/**
* 實現shiroRedisCacheManager
* @author tanaq
* @date 18-11-12 下午4:45
* @param [template]
* @throws
* @return com.cusc.icall.config.ShiroRedisCacheManager
*
*/
private ShiroRedisCacheManager cacheManager(){
return new ShiroRedisCacheManager(redisTemplate);
}
/**
*
* @title securityManager
* @description shiro安全管理器配置
* @param
* @return SecurityManager 返回型別
* @throws
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setCacheManager(cacheManager());
securityManager.setSessionManager(systemSessionManager());
securityManager.setRealm(systemShiroRealms());
return securityManager;
}
/**
*
* @title shiroFilterFactoryBean
* @description Shiro核心過濾器配置
* @param
* @return ShiroFilterFactoryBean 返回型別
* @throws
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager());
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
filterChainDefinitionMap.put("/ai/**", "authc");
filterChainDefinitionMap.put("/ai/*", "authc");
filterChainDefinitionMap.put("/druid/**","anon");
filterChainDefinitionMap.put("/**", "anon");
//配置Shiro預設跳轉至登入地址時,將以json格式資料返回
shiroFilterFactoryBean.setLoginUrl("/unAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
*
* @title defaultAdvisorAutoProxyCreator
* @description 開啟自動代理
* @param
* @return DefaultAdvisorAutoProxyCreator 返回型別
* @throws
*/
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
proxyCreator.setProxyTargetClass(true);
return proxyCreator;
}
/**
*
* @title authorizationAttributeSourceAdvisor
* @description 開啟許可權認證
* @param
* @return AuthorizationAttributeSourceAdvisor 返回型別
* @throws
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
三、ShiroRedisCacheManager 類實現shiro操作redis
本類已在上面的shiro配置中。給出實現:
public class ShiroRedisCacheManager extends AbstractCacheManager {
private RedisTemplate<byte[],byte[]> redisTemplate;
public ShiroRedisCacheManager(RedisTemplate redisTemplate){
this.redisTemplate = redisTemplate;
}
@Override
protected Cache createCache(String name) throws CacheException {
return new ShiroRedisCache(redisTemplate,name);
}
}
class ShiroRedisCache<K,V> implements Cache<K,V> {
private RedisTemplate redisTemplate;
private String prefix = "ntspcc_shiro_redis";
public String getPrefix() {
return prefix+":";
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public ShiroRedisCache(RedisTemplate redisTemplate){
this.redisTemplate = redisTemplate;
}
public ShiroRedisCache(RedisTemplate redisTemplate,String prefix){
this(redisTemplate);
this.prefix = prefix;
}
@Override
public V get(K k) throws CacheException {
if (k == null) {
return null;
}
byte[] bytes = getBytesKey(k);
return (V)redisTemplate.opsForValue().get(bytes);
}
@Override
public V put(K k, V v) throws CacheException {
if (k== null || v == null) {
return null;
}
byte[] bytes = getBytesKey(k);
redisTemplate.opsForValue().set(bytes, v);
return v;
}
@Override
public V remove(K k) throws CacheException {
if(k==null){
return null;
}
byte[] bytes =getBytesKey(k);
V v = (V)redisTemplate.opsForValue().get(bytes);
redisTemplate.delete(bytes);
return v;
}
@Override
public void clear() throws CacheException {
redisTemplate.getConnectionFactory().getConnection().flushDb();
}
@Override
public int size() {
return redisTemplate.getConnectionFactory().getConnection().dbSize().intValue();
}
@Override
public Set<K> keys() {
byte[] bytes = (getPrefix()+"*").getBytes();
Set<byte[]> keys = redisTemplate.keys(bytes);
Set<K> sets = new HashSet<>();
for (byte[] key:keys) {
sets.add((K)key);
}
return sets;
}
@Override
public Collection<V> values() {
Set<K> keys = keys();
List<V> values = new ArrayList<>(keys.size());
for(K k :keys){
values.add(get(k));
}
return values;
}
private byte[] getBytesKey(K key){
if(key instanceof String){
String prekey = this.getPrefix() + key;
return prekey.getBytes();
}else {
return SerializeUtil.serialize(key);
}
}
}
四、總結
上述整合完畢,操作redis可使用,可使用RedisTemplate.這裡已準備好了包裝類RedisTemplateUtils,功能十分完善,有需要請留言,當然也可在網上搜索。