
1 SecurityContextPersistenceFilter
通过观察Filter的名字,就能大概猜出来这个过滤器的作用,持久化SecurityContext实例org.springframework.security.web.context.SecurityContextPersistenceFilter

该 Filter 位于过滤器的顶端,所有过滤器的入口
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) { // 确保对于每个请求只应用一次过滤器
chain.doFilter(request, response); return;
} final boolean debug = logger.isDebugEnabled();
request.setAttribute(FILTER_APPLIED, Boolean.TRUE); if (forceEagerSessionCreation) {
HttpSession session = request.getSession(); if (debug && session.isNew()) {
logger.debug("Eagerly created session: " + session.getId());
}
} // 将 request/response 对象交给HttpRequestResponseHolder维持
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,response); //通过SecurityContextRepository接口的实现类装载SecurityContext实例
//HttpSessionSecurityContextRepository将产生SecurityContext实例的任务交给SecurityContextHolder.createEmptyContext()
//SecurityContextHolder再根据策略模式的不同,
//把任务再交给相应策略类完成SecurityContext的创建
//如果没有配置策略名称,则默认为
//ThreadLocalSecurityContextHolderStrategy,
//该类直接通过new SecurityContextImpl()创建实例
SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { //将产生的SecurityContext再通过SecurityContextHolder->
//ThreadLocalSecurityContextHolderStrategy设置到ThreadLocal
SecurityContextHolder.setContext(contextBeforeChainExecution); //继续把请求流向下一个过滤器执行
chain.doFilter(holder.getRequest(), holder.getResponse());
} finally { //先从SecurityContextHolder获取SecurityContext实例
SecurityContext contextAfterChainExecution = SecurityContextHolder
.getContext(); //关键性地除去SecurityContextHolder内容 - 在任何事情之前执行此操作
//再把SecurityContext实例从SecurityContextHolder中清空
//若没有清空,会受到服务器的线程池机制的影响
SecurityContextHolder.clearContext(); //将SecurityContext实例持久化到session中
repo.saveContext(contextAfterChainExecution, holder.getRequest(),
holder.getResponse());
request.removeAttribute(FILTER_APPLIED); if (debug) {
logger.debug("SecurityContextHolder now cleared, as request processing completed");
}
}
}通过源码中的注释,应该可以看出来,这个Filter的作用主要是创建一个空的SecurityContext(如果session中没有SecurityContext实例),然后持久化到session中。
作者:芥末无疆sss
链接:https://www.jianshu.com/p/a3630169351e
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
随时随地看视频