fq
zj
2025-06-13 08ea05f85c9dd77834e56a2b912b2c43ac8888cd
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package security.filter;
 
import java.io.IOException;
import java.lang.reflect.Method;
 
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
 
import security.SecUser;
 
public class HttpSessionContextIntegrationFilter implements Filter {
    private static final Logger logger=LoggerFactory.getLogger(HttpSessionContextIntegrationFilter.class);
    private boolean forceEagerSessionCreation = false;
    private boolean cloneFromHttpSession = false;
    public static final String SPRING_SECURITY_CONTEXT_KEY = "SPRING_SECURITY_CONTEXT";
    private Class contextClass = SecurityContextImpl.class;
 
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
 
    }
 
    private static final String FILTER_APPLIED = "_security_userContextFilter_filterApplied";
 
    private boolean observeOncePerRequest = true;
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession httpSession = safeGetSession(request,
                forceEagerSessionCreation);
        SecurityContext contextBeforeChainExecution = readSecurityContextFromSession(httpSession);
 
        httpSession = null;
 
        if (contextBeforeChainExecution == null) {
            contextBeforeChainExecution = generateNewContext();
 
            if (logger.isDebugEnabled()) {
                logger.debug("New SecurityContext instance will be associated with SecurityContextHolder");
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("Obtained a valid SecurityContext from SPRING_SECURITY_CONTEXT to "
                        + "associate with SecurityContextHolder: '"
                        + contextBeforeChainExecution + "'");
            }
        }
 
        try {
            // This is the only place in this class where
            // SecurityContextHolder.setContext() is called
            SecurityContextHolder.setContext(contextBeforeChainExecution);
            if ((request != null)
                    && (request.getAttribute(FILTER_APPLIED) == null)
                    && observeOncePerRequest) {
                if (request != null) {
                    request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
                }
                Object principal = security.SecurityAppUserHolder.getCurrentUser();
                if (principal instanceof SecUser) {
                    // 把用户放入request
                    request.setAttribute("_currentUser", principal);
                }
            }
 
            chain.doFilter(request, res);
        } finally {
            // Crucial removal of SecurityContextHolder contents - do this
            // before anything else.
            SecurityContextHolder.clearContext();
        }
 
    }
 
    public SecurityContext generateNewContext() throws ServletException {
        try {
            return (SecurityContext) this.contextClass.newInstance();
        } catch (InstantiationException ie) {
            throw new ServletException(ie);
        } catch (IllegalAccessException iae) {
            throw new ServletException(iae);
        }
    }
 
    private SecurityContext readSecurityContextFromSession(
            HttpSession httpSession) {
        if (httpSession == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("No HttpSession currently exists");
            }
 
            return null;
        }
 
        // Session exists, so try to obtain a context from it.
 
        Object contextFromSessionObject = httpSession
                .getAttribute(SPRING_SECURITY_CONTEXT_KEY);
 
        if (contextFromSessionObject == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("HttpSession returned null object for SPRING_SECURITY_CONTEXT");
            }
 
            return null;
        }
 
        // We now have the security context object from the session.
 
        // Clone if required (see SEC-356)
        if (cloneFromHttpSession) {
            Assert.isInstanceOf(Cloneable.class, contextFromSessionObject,
                    "Context must implement Clonable and provide a Object.clone() method");
            try {
                Method m = contextFromSessionObject.getClass().getMethod(
                        "clone", new Class[] {});
                if (!m.isAccessible()) {
                    m.setAccessible(true);
                }
                contextFromSessionObject = m.invoke(contextFromSessionObject,
                        new Object[] {});
            } catch (Exception ex) {
                ReflectionUtils.handleReflectionException(ex);
            }
        }
 
        if (!(contextFromSessionObject instanceof SecurityContext)) {
            logger.warn("SPRING_SECURITY_CONTEXT did not contain a SecurityContext but contained: '"
                    + contextFromSessionObject
                    + "'; are you improperly modifying the HttpSession directly "
                    + "(you should always use SecurityContextHolder) or using the HttpSession attribute "
                    + "reserved for this class?");
 
            return null;
        }
 
        // Everything OK. The only non-null return from this method.
 
        return (SecurityContext) contextFromSessionObject;
    }
 
    private HttpSession safeGetSession(HttpServletRequest request,
            boolean allowCreate) {
        try {
            return request.getSession(allowCreate);
        } catch (IllegalStateException ignored) {
            return null;
        }
    }
 
    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
 
    }
 
}