通过观察Filter的名字,就能大概猜出来这个过滤器的作用,持久化SecurityContext实例
org.springframework.security.web.context.SecurityContextPersistenceFilter
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中。