public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
        if (request.getAttribute(alreadyFilteredAttributeName) != null && filterOncePerRequest) {
            LOGGER.trace("Filter '{}' already executed.  Proceeding without invoking this filter.", getName());
            filterChain.doFilter(request, response);
            //noinspection deprecation
        } else if (/* added in 1.2: */ !isEnabled(request, response)
                ||    /* retain backwards compatibility: */ shouldNotFilter(request)) {
            LOGGER.debug("Filter '{}' is not enabled for the current request.  Proceeding without invoking this filter.",
                    getName());
            filterChain.doFilter(request, response);
        } else {
            // Do invoke this filter...
            LOGGER.trace("Filter '{}' not yet executed.  Executing now.", getName());
            request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);

            try {
                doFilterInternal(request, response, filterChain);
            } finally {
                // Once the request has finished, we're done and we don't
                // need to mark as 'already filtered' any more.
                request.removeAttribute(alreadyFilteredAttributeName);
            }
        }
    }
This {@code doFilter} implementation stores a request attribute for
"already filtered", proceeding without filtering again if the
attribute is already there.

@see #getAlreadyFilteredAttributeName
@see #shouldNotFilter
@see #doFilterInternal
web/src/main/java/org/apache/shiro/web/servlet/OncePerRequestFilter.java