我正在开发一个基于 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);
}
}
请您参考如下方法:
我看到了完全相同的行为,我认为这与异步调用被分为两个阶段这一事实有关。
首先,常规容器线程被踢出并生成临时响应,但该响应不会返回给客户端,而是被阻止,直到异步调度程序竞争为止。一旦异步线程完成处理,临时响应就会被异步线程中的真实响应替换并返回给客户端。
两个线程都经过相同的过滤器链。因此您会看到重复的调用。
如果您希望过滤器在从 OncePerRequestFilter
扩展后就被调用。它将检查您的过滤器在请求过程中是否已被调用(即使请求处理由 2 个阶段组成,每个阶段都由自己的线程处理)。