'SecurityContextPersistenceFilter clears SecurityContextHolder after filter chain is finished

I am currently studying Spring Security Fundamentals. I was reading documentation and source code as I like to get as much detailed information about what happens under the hood as possible. Everything is somewhat understandable except one thing:

SecurityContextPersistenceFilter Filter class is first filter of Spring Security according to this page The implementation of this class's doFilter() method looks like this:

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    if (request.getAttribute("__spring_security_scpf_applied") != null) {
        chain.doFilter(request, response);
    } else {
        request.setAttribute("__spring_security_scpf_applied", Boolean.TRUE);
        if (this.forceEagerSessionCreation) {
            HttpSession session = request.getSession();
            if (this.logger.isDebugEnabled() && session.isNew()) {
                this.logger.debug(LogMessage.format("Created session %s eagerly", session.getId()));
            }
        }

        HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
        SecurityContext contextBeforeChainExecution = this.repo.loadContext(holder);
        boolean var10 = false;

        try {
            var10 = true;
            SecurityContextHolder.setContext(contextBeforeChainExecution);
            if (contextBeforeChainExecution.getAuthentication() == null) {
                this.logger.debug("Set SecurityContextHolder to empty SecurityContext");
            } else if (this.logger.isDebugEnabled()) {
                this.logger.debug(LogMessage.format("Set SecurityContextHolder to %s", contextBeforeChainExecution));
            }

            chain.doFilter(holder.getRequest(), holder.getResponse());
            var10 = false;
        } finally {
            if (var10) {
                SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
                SecurityContextHolder.clearContext();
                this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
                request.removeAttribute("__spring_security_scpf_applied");
                this.logger.debug("Cleared SecurityContextHolder to complete request");
            }
        }

        SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
        SecurityContextHolder.clearContext();
        this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
        request.removeAttribute("__spring_security_scpf_applied");
        this.logger.debug("Cleared SecurityContextHolder to complete request");
    }
}

The question I have is this: obviously, after filter chain has done its job, SecurityContextHolder.clearContext() method is called either in finally block or at the end of the method. However I know that, I can still access SecurityContext object with SecurityContextHolder.getContext() in my controller and service layer. How is it possible if above code clears SecurityContextHolder? Am I missing something?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source