文章目录
- 1.SpringSecurity 请求间共享认证信息
- 2.SecurityContextPersistenceFilter 过滤器
1.SpringSecurity 请求间共享认证信息
一般认证成功后的用户信息是通过 Session 在多个请求之间共享,那么 Spring Security 中是如何实现将已认证的用户信息对象 Authentication 与 Session 绑定的进行具体分析。
在前面讲解认证成功的处理方法 successfulAuthentication() 时,有以下代码:
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response, FilterChain chain, Authentication authResult)
throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Authentication success. Updating SecurityContextHolder to contain: "
+ authResult);
}
SecurityContextHolder.getContext().setAuthentication(authResult);
rememberMeServices.loginSuccess(request, response, authResult);
// Fire event
if (this.eventPublisher != null) {
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
authResult, this.getClass()));
}
successHandler.onAuthenticationSuccess(request, response, authResult);
}
查 看 SecurityContext 接 口 及 其 实 现 类 SecurityContextImpl , 该 类 其 实 就 是 对Authentication 的封装:
SecurityContext 就是对Authentication的封装
查 看 SecurityContextHolder 类 , 该 类 其 实 是 对 ThreadLocal 的 封 装 , 存 储SecurityContext 对象:
默认使用的是MODE_THREADLOCAL模式, 默认使用ThreadLocalSecurityContextHolderStrategy
创建strategy, 内部是ThreadLocal对SecurityContext的存储。
2.SecurityContextPersistenceFilter 过滤器
响应会通过 SecurityContextPersistenceFilter 过滤器,该过滤器的位置在所有过滤器的最前面,请求到来先进它,响应返回最后一个通过它,所以在该过滤器中处理已认证的用户信息对象 Authentication 与 Session 绑定。
当请求到来时,请求首先经过该过滤器,该过滤器会判断当前请求的 Session 是否存有 SecurityContext 对象,如果有则将该对象取出再次放入 SecurityContextHolder 中,之后该请求所在的线程获得认证用户信息,后续的资源访问不需要进行身份认证;当响应再次返回时,该过滤器同样从 SecurityContextHolder 取出SecurityContext 对象,放入 Session 中。
SecurityContextPersistenceFilter#doFilter()