在Spring Boot项目中过滤两次调用[重复]

Posted

技术标签:

【中文标题】在Spring Boot项目中过滤两次调用[重复]【英文标题】:Filter get invoke twice in Spring Boot project [duplicate] 【发布时间】:2016-12-27 08:12:34 【问题描述】:

我有一个扩展 AbstractAuthenticationProcessingFilter 的过滤器。

在我下面的安全配置类中,

  @Override
    protected void configure(final HttpSecurity http) throws Exception 
        http.addFilterBefore(getMyFilter(), BasicAuthenticationFilter.class);
        http.addFilterAfter(getMyFilter2(), MyFilter.class);
        http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
    

    private MyFilter getMyFilter() 
        return new MyFilter(properties, apiConsumer);
    

当我使用邮递员调用 REST 端点时,MyFilterdoFilter 方法会被命中两次。在这两种情况下,它在ServletRequest 中都有相同的requestedSessionIdstrippedServletPath

但是扩展GenericFilterBeanMyFilter2 只能调用一次。

过滤器执行顺序为MyFilter.doFilter -> MyFilter2.doFilter -> MyFilter.doFilter

原因是什么?如何找到根本原因?

【问题讨论】:

我已经用@Component 注释定义了 MyFilter。当我删除该注释时,它只命中一次 【参考方案1】:

我猜这种行为只出现在第一次请求时(出现基本身份验证弹出窗口时)。如果是这样,那么这是因为基本身份验证规范及其在 Spring 的BasicAuthenticationFilter 中的实现。

当您第一次调用服务时,Spring 会在您的请求中查找 Authorization 标头,如果不存在,它会将带有 WWW-Authenticate: Basic 标头的响应发送到您的浏览器。 当您的浏览器收到带有该特定标头的此响应时,它会显示身份验证弹出窗口。当您输入用户名和密码时,您的浏览器会发出另一个请求(现在带有适当的 Authorization 标头),现在 Spring 可以正确授权您的请求。

问题在于,在整个过程中,Spring 处理过滤器链两次(在每个请求上)。

您可以在此处阅读有关基本身份验证的更多信息: https://en.wikipedia.org/wiki/Basic_access_authentication

【讨论】:

谢谢,但我正在使用邮递员来调用请求。我没有收到这样的身份验证弹出窗口。 如果您使用的是邮递员并且它是Basic Auth 授权,那么它将以相同的方式工作(邮递员自己处理这个多步身份验证过程) 你的示例控制器是什么样子的? 我有 @RequestMapping 和 GET 和 @PreAuthorize("hasAuthority('student')") 注释 好吧,我已经用@Component 注释定义了 MyFilter。当我删除该注释时,它只会命中一次。

以上是关于在Spring Boot项目中过滤两次调用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

spring boot webflux中如何根据条件进行两次删除操作?

Vue+axios+spring boot遇到的问题(跨域请求)

自定义过滤器被调用两次[重复]

WebFilter bean 在安全的 Spring Boot Webflux 应用程序中调用了两次

未调用 Spring Boot Rest API 过滤器

Spring Task每次都会调用两次的问题