0%

web如何取得用户信息

web如何取得用户信息

之前说过SecurityContextHolder默认使用的是ThreadLocal来进行存储的,而且每次都会清除,但是web每次请求都会验证用户权限,这是如何做到的呢?

这是通过SecurityContextPersistenceFilter来实现的,每次请求过来都会session中来获取SecurityContext,然后设置到SecurityContextHolder中,请求结束后再清除掉

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
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;

if (request.getAttribute(FILTER_APPLIED) != null) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
return;
}

request.setAttribute(FILTER_APPLIED, Boolean.TRUE);


HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
response);
// 从session获取SecurityContext
SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

try {
// 将SecurityContext存入SecurityContextHolder
SecurityContextHolder.setContext(contextBeforeChainExecution);

chain.doFilter(holder.getRequest(), holder.getResponse());

}
finally {
SecurityContext contextAfterChainExecution = SecurityContextHolder
.getContext();
// Crucial removal of SecurityContextHolder contents - do this before anything
// else.
SecurityContextHolder.clearContext();
// 存储SecurityContext
repo.saveContext(contextAfterChainExecution, holder.getRequest(),
holder.getResponse());
request.removeAttribute(FILTER_APPLIED);
}
}

loadContext获取SecurityContext

使用HttpSessionSecurityContextRepository

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
HttpServletRequest request = requestResponseHolder.getRequest();
HttpServletResponse response = requestResponseHolder.getResponse();
HttpSession httpSession = request.getSession(false);
// 从session中获取SecurityContext
SecurityContext context = readSecurityContextFromSession(httpSession);

if (context == null) {

context = generateNewContext();

}

SaveToSessionResponseWrapper wrappedResponse = new SaveToSessionResponseWrapper(
response, request, httpSession != null, context);
requestResponseHolder.setResponse(wrappedResponse);

return context;
}

从session中获取SecurityContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private SecurityContext readSecurityContextFromSession(HttpSession httpSession) {
final boolean debug = logger.isDebugEnabled();

if (httpSession == null) {
return null;
}

// Session exists, so try to obtain a context from it.

Object contextFromSession = httpSession.getAttribute(springSecurityContextKey);

if (contextFromSession == null) {
return null;
}

// Everything OK. The only non-null return from this method.

return (SecurityContext) contextFromSession;
}

存储SecurityContext

1
2
3
4
5
6
7
8
9
10
public void saveContext(SecurityContext context, HttpServletRequest request,
HttpServletResponse response) {
SaveContextOnUpdateOrErrorResponseWrapper responseWrapper = WebUtils
.getNativeResponse(response,
SaveContextOnUpdateOrErrorResponseWrapper.class);

if (!responseWrapper.isContextSaved()) {
responseWrapper.saveContext(context);
}
}
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
protected void saveContext(SecurityContext context) {
final Authentication authentication = context.getAuthentication();
HttpSession httpSession = request.getSession(false);

// See SEC-776
if (authentication == null || trustResolver.isAnonymous(authentication)) {

if (httpSession != null && authBeforeExecution != null) {
// SEC-1587 A non-anonymous context may still be in the session
// SEC-1735 remove if the contextBeforeExecution was not anonymous
httpSession.removeAttribute(springSecurityContextKey);
}
return;
}

if (httpSession == null) {
httpSession = createNewSessionIfAllowed(context);
}

// If HttpSession exists, store current SecurityContext but only if it has
// actually changed in this thread (see SEC-37, SEC-1307, SEC-1528)
if (httpSession != null) {
// We may have a new session, so check also whether the context attribute
// is set SEC-1561
if (contextChanged(context)
|| httpSession.getAttribute(springSecurityContextKey) == null) {
// 存到session中
httpSession.setAttribute(springSecurityContextKey, context);


}
}
}

欢迎关注我的其它发布渠道