【问题标题】:How does the doFilter method of the FilterChainProxy work?FilterChainProxy 的 doFilter 方法是如何工作的?
【发布时间】:2015-03-29 23:07:51
【问题描述】:

我正在浏览 org.springframework.security.web.FilterChainProxy 类的源代码。我想了解它的 doFilter 方法是如何工作的。以下是代码。

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException 
{
    FilterInvocation fi = new FilterInvocation(request, response, chain);
    List<Filter> filters = getFilters(fi.getRequestUrl());

    if (filters == null || filters.size() == 0) {
        if (logger.isDebugEnabled()) {
            logger.debug(fi.getRequestUrl() +
                    filters == null ? " has no matching filters" : " has an empty filter list");
        }

        chain.doFilter(request, response);

        return;
    }

    VirtualFilterChain virtualFilterChain = new VirtualFilterChain(fi, filters);
    virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());

}

我的理解是,如果我在 web.xml 中定义与 Spring 无关的自定义过滤器,它们将包含在传递给 FilterChainProxy 的 FilterChain 对象中(我知道这是通过 DelegatingFilterProxy 发生的)。对吗?

我认为当 web.xml 中定义了非弹簧过滤器并且应用程序上下文中没有定义过滤器时,IF 块会被执行。

这里的 VirtualFilterChain 满足应用程序文本中定义的过滤器。

If 块中有一个 return 语句可以防止 VirtualFilterChain 部分被执行。

但这如何处理 web.xml 中定义的过滤器和应用程序上下文中定义的过滤器?

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:

    “filterChain”参数指的是 web.xml 中定义的 Servlet 过滤器。在 DelegatingFilterProxy.java 中查看这段代码

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
    
        // Lazily initialize the delegate if necessary.
        Filter delegateToUse = this.delegate;
        if (delegateToUse == null) {
            ...
        }
    
        // Let the delegate perform the actual doFilter operation.
        invokeDelegate(delegateToUse, request, response, filterChain);
    }
    

    invokeDelegate(...) 是调用 FilterChainProxy 的 doFilter(...) 方法的原因。

    List&lt;Filter&gt; filters = getFilters(fi.getRequestUrl());

    生成与给定 url 匹配的 Spring Security 过滤器列表(一些过滤器在this section 中列出)。

    如果没有 Spring Security 过滤器与 requestUrl 匹配,则执行将继续执行 web.xml 中定义的其余过滤器。这就是 if() 块的用途。

    virtualFilterChain.doFilter(fi.getRequest(), fi.getResponse());
    

    这是 Spring Security 过滤器的 doFilter(...) 方法被调用的地方。因此,例如,如果您将 UsernamePasswordAuthenticationFilter 作为配置的过滤器之一,那么 virtualFilterChain.doFilter(...) 最终将调用 UsernamePasswordAuthenticationFilter 的 doFilter(...) 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-11
      • 2019-05-20
      • 2012-04-21
      • 2016-07-26
      • 2018-06-26
      • 1970-01-01
      相关资源
      最近更新 更多