除虫计划 Spring Security过滤器重复调用

本文将介绍 Spring Security 中自定义过滤器可能会遇到的重复调用问题,并说明解决方法。

一、问题

Spring Boot 集成 Spring Security,希望在 Spring Security 的过滤器链中增加自定义过滤器,但却遇到了过滤器被重复调用的问题。

二、复现

做法为:

  • 自定义过滤器
  • 将自定义过滤器配置到 Spring Security 的过滤器链中

编写代码如下:

  • 自定义过滤器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Component
    public class MyFilter extends GenericFilterBean {

    @Autowired
    JWTUtil JWTUtil;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    System.out.println("调用了一次");
    chain.doFilter(request, response);
    }

    }
  • Spring Security 配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    MyFilter myFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http
    .addFilterBefore(myFilter, UsernamePasswordAuthenticationFilter.class);
    }

    }

    代码运行时出现过滤器重复调用问题,如下:

三、原因

如果自定义过滤器被 @Bean@Component 注解,生成 Bean 后交由 Spring 容器托管,则它会被自动添加至 Spring MVC 的过滤器链中。

因此,这里的自定义过滤器被自动添加到一个过滤器链,又被手动添加到另一个过滤器链,才导致出现执行两次的情况。

四、解决方法

过滤器不要让 Spring 托管。

参考