【问题标题】:Filter get invoke twice in Spring Boot project [duplicate]在Spring Boot项目中过滤两次调用[重复]
【发布时间】: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。当我删除该注释时,它只命中一次

标签: java spring spring-security spring-boot


【解决方案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。当我删除该注释时,它只会命中一次。
猜你喜欢
  • 2021-01-22
  • 1970-01-01
  • 2020-03-09
  • 2019-04-12
  • 2021-07-12
  • 2021-12-12
  • 2015-08-19
  • 2020-10-22
  • 2015-06-29
相关资源
最近更新 更多