SecurityContextPersistenceFilter是承接容器的session与spring security的重要filter,主要工作是从session中获取SecurityContext,然后放到上下文中,之后的filter大多依赖这个来获取登录态。其主要是通过HttpSessionSecurityContextRepository来存取的。
public class SecurityContextPersistenceFilter extends GenericFilterBean { static final String FILTER_APPLIED = "__spring_security_scpf_applied"; 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) { // 这个就是确保一个request只会走一次SecurityContextPersistenceFilter chain.doFilter(request, response); return; } // 给request打标记,说明这个Filter已经执行过一次了。 request.setAttribute(FILTER_APPLIED, Boolean.TRUE); if (forceEagerSessionCreation) { // 要不要先创建session HttpSession session = request.getSession(); } HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,response); // 通过SecurityContextRepository加载SecurityContext // 默认使用的是HttpSessionSecurityContxtReposity // 这个就是说,默认是从session中获取。如果session里面获取不到就创建一个新的SecurityContext SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { // 将 SecurityContext 丢入 SecurityContextHolder SecurityContextHolder.setContext(contextBeforeChainExecution); //执行其他拦截器 chain.doFilter(holder.getRequest(), holder.getResponse()); } finally { // 在其他拦截器执行完后,再将SecurityContext 从 SecurityContextHolder中移除 SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext(); SecurityContextHolder.clearContext(); // 保存经过其他拦截器 *** 作过后的SecurityContext到指定地方 //repo的默认值是HttpSessionSecurityContxtReposity // 也就是保存到session中去 repo.saveContext(contextAfterChainExecution, holder.getRequest(),holder.getResponse()); request.removeAttribute(FILTER_APPLIED); } } }
简述流程:
1.从SecurityContextRepository中获取SecurityContext
2.将SecurityContext存入SecurityContextHolder中
3.执行其他过滤器,对SecurityContext进行处理
4.在其他的执行完后,将SecurityContext从SecurityContextHolder中清除,并通过SecurityContextRepository进行回写。
Spring Security Web提供的类HttpSessionSecurityContextRepository是一个SecurityContextRepository接口的实现,用于在HttpSession中保存安全上下文(security context),这样属于同一个HttpSession的多个请求,就能够利用此机制访问同一安全上下文了。
public interface SecurityContextRepository { //获取所提供请求的安全上下文。对于未经身份验证的用户,应返回空上下文实现。此方法不应返回null。 SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder); //在请求完成时存储安全上下文。 void saveContext(SecurityContext context, HttpServletRequest request,HttpServletResponse response); //允许查询存储库是否包含当前请求的安全上下文。 boolean containsContext(HttpServletRequest request); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)