springboot1.5.3+shiro1.3.2+redis單節點及集群集成
項目要求直接在配置文件中可切換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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
上面是單節點配置,集群去掉注釋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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
上述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
* @date 18-11-12 下午4:45
* @param [template]
* @throws
* @return 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;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
三、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);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
四、總結
上述集成完畢,操作redis可使用,可使用RedisTemplate.這裡已準備好了包裝類RedisTemplateUtils,功能十分完善,有需要請留言,當然也可在網上搜索。
打開今日頭條,查看更多精彩圖片※聚合查詢慢——詳解Global Ordinals與High Cardinality
※Servlet中幾個監聽器Listener的使用實例
TAG:程序員小新人學習 |