赞
踩
SecurityContextPersistenceFilter有两个主要任务:
通过SecurityContextPersistenceFilter的这种机制,在整个请求处理过程中,开发人员都可以通过使用SecurityContextHolder获取当前访问用户的安全上下文信息。
缺省情况下,SecurityContextPersistenceFilter使用的SecurityContextRepository是HttpSessionSecurityContextRepository,也就是将安全上下文的信息保存在用户的会话中。
为了解决不同Serlvet容器上,尤其是weblogic上的兼容性问题,此Filter必须在整个request处理过程中被调用最多一次。
该Filter也必须在任何认证机制逻辑发生之前被调用。因为这些认证机制都依赖于SecurityContextHolder所包含的安全上下文对象。
public class SecurityContextPersistenceFilter extends GenericFilterBean { // 确保该Filter在一个request处理过程中最多被调到用一次的机制: // 一旦该Fitler被调用过,他会在当前request增加该属性值为true,利用此标记 // 可以避免Filter被调用二次。 static final String FILTER_APPLIED = "__spring_security_scpf_applied"; // 安全上下文存储库 private SecurityContextRepository repo; private boolean forceEagerSessionCreation = false; public SecurityContextPersistenceFilter() { // 缺省使用http session 作为安全上下文对象存储 this(new HttpSessionSecurityContextRepository()); } public SecurityContextPersistenceFilter(SecurityContextRepository repo) { this.repo = repo; } 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 // 检查调用标志,如果request上已经存在属性FILTER_APPLIED, // 表明该Filter在该request的处理过程中已经被调用过 chain.doFilter(request, response); return; } final boolean debug = logger.isDebugEnabled(); // 设置该Filter已经被调用的标记 request.setAttribute(FILTER_APPLIED, Boolean.TRUE); if (forceEagerSessionCreation) { HttpSession session = request.getSession(); if (debug && session.isNew()) { logger.debug("Eagerly created session: " + session.getId()); } } HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response); // 从安全上下文存储库(缺省是http session)中读取安全上下文对象 SecurityContext contextBeforeChainExecution = repo.loadContext(holder); try { // 设置安全上下文对象到SecurityContextHolder然后才继续Filter chain的调用 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并将最新的 // 安全上下文对象保存回安全上下文存储库(缺省是http session) SecurityContextHolder.clearContext(); repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); request.removeAttribute(FILTER_APPLIED); if (debug) { logger.debug("SecurityContextHolder now cleared, as request processing completed"); } } } public void setForceEagerSessionCreation(boolean forceEagerSessionCreation) { this.forceEagerSessionCreation = forceEagerSessionCreation; } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。