【问题标题】:Why filter chain is called twice for an asynchronous endpoint为什么异步端点的过滤器链被调用两次
【发布时间】:2020-10-22 03:37:22
【问题描述】:

我正在开发一个基于 Spring Boot 的应用程序。我注意到,对于异步端点,身份验证过滤器被调用两次,对于常规端点,它被调用一次。我找不到原因,但我在网络 https://jira.spring.io/browse/SPR-12608 中发现了一个问题,据说异步端点的过滤器在异步端点执行之前和之后被调用了两次。它将解释双重身份验证调用。我想知道这是预期的行为,为什么这样做以及如何避免双重身份验证。

更新: 我找到了一种方法来避免在异步端点完成后第二次触发过滤器。我需要做的是分析分配给请求的调度程序类型,如果它是异步的 - 在过滤器链上继续进行。我在过滤器中添加了以下方法:

@Override
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
    if (request.getDispatcherType() == DispatcherType.ASYNC) {
        filterChain.doFilter(request, response);
    } else {
        super.doFilter(request, response, filterChain);
    }
}

【问题讨论】:

    标签: spring spring-boot spring-security


    【解决方案1】:

    我看到了完全相同的行为,我认为这与异步调用被分成两个阶段这一事实有关。

    首先,常规容器线程被启动并生成一个临时响应,但该响应不会返回给客户端,它会被阻止直到异步调度程序竞争。一旦异步线程完成处理临时响应,就会被来自异步线程的真实响应替换并返回给客户端。

    两个线程都经过相同的过滤器链。因此,您会看到重复调用。

    如果您希望过滤器被调用一次,您应该从OncePerRequestFilter 扩展。它将检查您的过滤器是否在请求过程中已被调用(即使请求处理由 2 个阶段组成,每个阶段都由各自的线程处理)。

    【讨论】:

      【解决方案2】:

      我对 AbstractAuthenticationProcessingFilter 类的具体实现有同样的问题,我相信可以解决它最好创建一个实现 OncePerRequestFilter 的 whaterver 类的自定义实现,在我的特定情况下,我创建了一个 @987654323 的实现@。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-23
        • 2015-08-19
        • 2017-04-16
        • 2021-05-21
        • 1970-01-01
        • 2021-07-13
        • 2021-11-25
        • 2015-12-24
        相关资源
        最近更新 更多