首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

聊聊SecurityContextPersistenceFilter(2)

聊聊SecurityContextPersistenceFilter(2)

SecurityContextPersistenceFilter

spring-security-web-4.2.3.RELEASE-sources.jar!/org/springframework/security/web/context/SecurityContextPersistenceFilter.java

    /**
     * Populates the {@link SecurityContextHolder} with information obtained from the
     * configured {@link SecurityContextRepository} prior to the request and stores it back in
     * the repository once the request has completed and clearing the context holder. By
     * default it uses an {@link HttpSessionSecurityContextRepository}. See this class for
     * information <tt>HttpSession</tt> related configuration options.
     * <p>
     * This filter will only execute once per request, to resolve servlet container
     * (specifically Weblogic) incompatibilities.
     * <p>
     * This filter MUST be executed BEFORE any authentication processing mechanisms.
     * Authentication processing mechanisms (e.g. BASIC, CAS processing filters etc) expect
     * the <code>SecurityContextHolder</code> to contain a valid <code>SecurityContext</code>
     * by the time they execute.
     * <p>
     * This is essentially a refactoring of the old
     * <tt>HttpSessionContextIntegrationFilter</tt> to delegate the storage issues to a
     * separate strategy, allowing for more customization in the way the security context is
     * maintained between requests.
     * <p>
     * The <tt>forceEagerSessionCreation</tt> property can be used to ensure that a session is
     * always available before the filter chain executes (the default is <code>false</code>,
     * as this is resource intensive and not recommended).
     *
     * @author Luke Taylor
     * @since 3.0
     */
    public class SecurityContextPersistenceFilter extends GenericFilterBean {
     
        static final String FILTER_APPLIED = "__spring_security_scpf_applied";
     
        private SecurityContextRepository repo;
     
        private boolean forceEagerSessionCreation = false;
     
        public SecurityContextPersistenceFilter() {
            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
                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());
                }
            }
     
            HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
                    response);
            SecurityContext contextBeforeChainExecution = repo.loadContext(holder);
     
            try {
                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.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;
        }
    }
    复制代码

    SecurityContextPersistenceFilter是承接容器的session与spring security的重要filter,主要工作是从session中获取SecurityContext,然后放到上下文中,之后的filter大多依赖这个来获取登录态。其主要是通过HttpSessionSecurityContextRepository来存取的。
返回列表