MrShi
2024-11-01 deb4575b72443cf906946a9fb28a557c16556fb9
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
136
137
138
139
package com.doumee.config.shiro;
 
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.SerializationUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
 
import java.io.Serializable;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
 
//@Component
@Slf4j
@SuppressWarnings({ "rawtypes", "unchecked" })
public class ShiroRedisSessionDAO  implements SessionDAO {
// Session超时时间,单位为毫秒
private static final String KEY_PREFIX = "shiro:session:";
    private long expireTime = 120000;
    @Autowired
    private ShiroTokenManager shiroTokenManager;
    @Autowired
    private RedisTemplate redisTemplate;// Redis操作类,对这个使用不熟悉的,可以参考前面的博客
 
    public ShiroRedisSessionDAO() {
 
        super();
 
    }
 
    public ShiroRedisSessionDAO(long expireTime, StringRedisTemplate redisTemplate) {
 
        super();
 
        this.expireTime = expireTime;
 
        this.redisTemplate = redisTemplate;
 
    }
 
    @Override // 更新session
 
    public void update(Session session) throws UnknownSessionException {
 
        System.out.println("===============update================");
 
        if (session == null || session.getId() == null) {
            return;
        }
        session.setTimeout(expireTime);
        byte[] bytes = SerializationUtils.serialize((Serializable) session);
        redisTemplate.opsForValue().set(KEY_PREFIX+session.getId(), bytes, expireTime, TimeUnit.MILLISECONDS);
    }
 
    @Override // 删除session
 
    public void delete(Session session) {
 
        System.out.println("===============delete================");
 
        if (null == session) {
 
            return;
 
        }
 
        redisTemplate.opsForValue().getOperations().delete(KEY_PREFIX+session.getId());
 
    }
 
    @Override// 获取活跃的session,可以用来统计在线人数,如果要实现这个功能,可以在将session加入redis时指定一个session前缀,统计的时候则使用keys("session-prefix*")的方式来模糊查找redis中所有的session集合
    public Collection getActiveSessions() {
 
        System.out.println("==============getActiveSessions=================");
 
        return redisTemplate.keys("*");
 
    }
 
    @Override
    public Serializable create(Session session) {
 
        System.out.println("===============doCreate================");
 
        if (session == null) {
            log.error("session is null");
            throw new UnknownSessionException("session is null");
        }
        Serializable sessionId = shiroTokenManager.build();
        ((SimpleSession)session).setId(sessionId);
        byte[] bytes = SerializationUtils.serialize((Serializable) session);
        redisTemplate.opsForValue().set(session.getId(), bytes, expireTime, TimeUnit.MILLISECONDS);
        return sessionId;
 
    }
    public Session readSession(Serializable sessionId) throws UnknownSessionException{
        if (sessionId == null) {
            log.warn("session id is null");
            return null;
        }
        if (sessionId instanceof String) {
            // 对SessionId进行验证(可用于防止Session捕获、暴力捕捉等一系列安全问题,最终安全性取决于check如何实现)
            shiroTokenManager.check((String) sessionId);
        }
        log.debug("read session from cache");
 
        SimpleSession simpleSession = (SimpleSession) SerializationUtils.deserialize((byte[])redisTemplate.opsForValue().get(KEY_PREFIX+sessionId));
       return simpleSession;
 
    }
 
    public long getExpireTime() {
 
        return expireTime;
 
    }
 
    public void setExpireTime(long expireTime) {
 
        this.expireTime = expireTime;
 
    }
 
    public RedisTemplate getRedisTemplate() {
 
        return redisTemplate;
 
    }
 
    public void setRedisTemplate(RedisTemplate redisTemplate) {
 
        this.redisTemplate = redisTemplate;
 
    }
}