[测评系统]--测评系统核心代码库
林致杰
2022-03-07 c63c907840e9c194d92ad490efd5f76c7f67a900
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
package com.ots.framework.shiro.web.filter.kickout;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ots.common.constant.ShiroConstants;
import com.ots.common.utils.ServletUtils;
import com.ots.common.utils.security.ShiroUtils;
import com.ots.framework.web.domain.AjaxResult;
import com.ots.project.system.user.domain.User;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.Deque;
 
public class KickoutSessionFilter extends AccessControlFilter {
    private final static ObjectMapper objectMapper = new ObjectMapper();
    
    private int maxSession = -1;
    
    private Boolean kickoutAfter = false;
    
    private String kickoutUrl;
    private SessionManager sessionManager;
    private Cache<String, Deque<Serializable>> cache;
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o)
            throws Exception {
        return false;
    }
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        Subject subject = getSubject(request, response);
        if (!subject.isAuthenticated() && !subject.isRemembered() || maxSession == -1) {
            
            return true;
        }
        try {
            Session session = subject.getSession();
            
            User user = ShiroUtils.getSysUser();
            String loginName = user.getLoginName();
            Serializable sessionId = session.getId();
            
            Deque<Serializable> deque = cache.get(loginName);
            if (deque == null) {
                
                deque = new ArrayDeque<Serializable>();
            }
            
            if (!deque.contains(sessionId) && session.getAttribute("kickout") == null) {
                
                deque.push(sessionId);
                
                cache.put(loginName, deque);
            }
            
            while (deque.size() > maxSession) {
                Serializable kickoutSessionId = null;
                
                if (kickoutAfter) {
                    
                    kickoutSessionId = deque.removeFirst();
                } else {
                    
                    kickoutSessionId = deque.removeLast();
                }
                
                cache.put(loginName, deque);
                try {
                    
                    Session kickoutSession = sessionManager.getSession(new DefaultSessionKey(kickoutSessionId));
                    if (null != kickoutSession) {
                        
                        kickoutSession.setAttribute("kickout", true);
                    }
                } catch (Exception e) {
                    
                }
            }
            
            if ((Boolean) session.getAttribute("kickout") != null && (Boolean) session.getAttribute("kickout") == true) {
                
                subject.logout();
                saveRequest(request);
                return isAjaxResponse(request, response);
            }
            return true;
        } catch (Exception e) {
            return isAjaxResponse(request, response);
        }
    }
    private boolean isAjaxResponse(ServletRequest request, ServletResponse response) throws IOException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        if (ServletUtils.isAjaxRequest(req)) {
            AjaxResult ajaxResult = AjaxResult.error("您已在别处登录,请您修改密码或重新登录");
            ServletUtils.renderString(res, objectMapper.writeValueAsString(ajaxResult));
        } else {
            WebUtils.issueRedirect(request, response, kickoutUrl);
        }
        return false;
    }
    public void setMaxSession(int maxSession) {
        this.maxSession = maxSession;
    }
    public void setKickoutAfter(boolean kickoutAfter) {
        this.kickoutAfter = kickoutAfter;
    }
    public void setKickoutUrl(String kickoutUrl) {
        this.kickoutUrl = kickoutUrl;
    }
    public void setSessionManager(SessionManager sessionManager) {
        this.sessionManager = sessionManager;
    }
    
    public void setCacheManager(CacheManager cacheManager) {
        
        this.cache = cacheManager.getCache(ShiroConstants.SYS_USERCACHE);
    }
}