spring如何保证每个请求的OncePerRequestFilter只执行一次

我浏览了与OncePerRequestFilter有关的其他问题,但从技术上讲,它并不清楚。

基本上,我已经实现了一个启用了安全功能的spring boot项目。使用JPA,H2数据库来验证用户。

我读到,OncePerRequestFilter对每个请求只执行一次,所以我在我的自定义过滤器中扩展了它。

 public class AuthFilter extends OncePerRequestFilter{
        
        public static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
    
        

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        log.info(" ##### INSIDE AUTH FILTER ####");
        log.info(" ##### INSIDE AUTH FILTER #### method::"+request.getMethod());
        log.info(" ##### INSIDE AUTH FILTER #### Servlet path::"+request.getServletPath());
        log.info(" ##### INSIDE AUTH FILTER #### attibute names ::"+getAlreadyFilteredAttributeName());
        log.info(" ##### INSIDE AUTH FILTER #### URI ::" +request.getRequestURI());
        log.info(" ##### INSIDE AUTH FILTER #### URL ::"+request.getRequestURL());
        filterChain.doFilter(request, response);
        
    }
        
        
    
    }

而我的控制器方法看起来像这样。

@GetMapping("/hello")
    public String hello() {
        log.info(" ########  INSIDE SIGN IN ########");
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken("jay", "root"));
        
        SecurityContextHolder.getContext().setAuthentication(authentication);
        
        log.info(" ########  INSIDE SIGN IN ######## Authentication completed");
        return "Hello World !!";
    }

当项目启动和运行时,当我调用http://localhost:8080/hello时,我的自定义过滤器被多次调用。我怎样才能确保它只被执行一次?

我的Auth过滤器的配置。

@Override
protected void configure(HttpSecurity http) throws Exception {
    System.out.println(" ##########   inside configure HHTTP ##########");
    http.cors().and().csrf().disable()
        .authorizeRequests()
        .antMatchers("/admin").hasAuthority("ADMIN")
        .antMatchers("/helloAll").hasAuthority("ADMIN")
        .antMatchers("/hello").hasAuthority("ADMIN")
        .antMatchers("/user").hasAnyAuthority("USER","ADMIN")
        .antMatchers("/**").permitAll()
        .and().formLogin();
    
    http.addFilterBefore(getAuthFilter(), UsernamePasswordAuthenticationFilter.class);
    //http.addFilterBefore(getFilterTestBean(), UsernamePasswordAuthenticationFilter.class);
}

@Bean
    public AuthFilter getAuthFilter() {
        return new AuthFilter();
    }

@Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        System.out.println(" ##########   inside configure ##########");
        auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder());
    }

下面是我的日志堆栈。

2021-06-30 15:31:54.223 DEBUG 9220 --- [nio-8080-exec-3] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to spring.security.spring.token.jwttoken.security.HelloWorldController#hello()
2021-06-30 15:31:54.223  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER ####
2021-06-30 15:31:54.223  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### method::GET
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### Servlet path::/hello
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### attibute names ::getAuthFilter.FILTERED
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URI ::/hello
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URL ::http://localhost:8080/hello
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.FilterTest     :  ######  Inside Filter Test ####
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### method::GET
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### Servlet path::/hello
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URI ::/hello
2021-06-30 15:31:54.224  INFO 9220 --- [nio-8080-exec-3] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URL ::http://localhost:8080/hello
2021-06-30 15:31:54.265 DEBUG 9220 --- [nio-8080-exec-4] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
2021-06-30 15:31:54.266  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER ####
2021-06-30 15:31:54.266  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### method::GET
2021-06-30 15:31:54.266  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### Servlet path::/login
2021-06-30 15:31:54.266  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### attibute names ::getAuthFilter.FILTERED
2021-06-30 15:31:54.266  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URI ::/login
2021-06-30 15:31:54.266  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URL ::http://localhost:8080/login
2021-06-30 15:31:54.267  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.FilterTest     :  ######  Inside Filter Test ####
2021-06-30 15:31:54.267  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### method::GET
2021-06-30 15:31:54.267  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### Servlet path::/login
2021-06-30 15:31:54.267  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URI ::/login
2021-06-30 15:31:54.267  INFO 9220 --- [nio-8080-exec-4] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URL ::http://localhost:8080/login
2021-06-30 15:32:05.252 DEBUG 9220 --- [nio-8080-exec-5] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped to ResourceHttpRequestHandler [Classpath [META-INF/resources/], Classpath [resources/], Classpath [static/], Classpath [public/], ServletContext [/]]
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER ####
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### method::POST
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### Servlet path::/login
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### attibute names ::getAuthFilter.FILTERED
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URI ::/login
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URL ::http://localhost:8080/login
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.FilterTest     :  ######  Inside Filter Test ####
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### method::POST
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### Servlet path::/login
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URI ::/login
2021-06-30 15:32:05.267  INFO 9220 --- [nio-8080-exec-5] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URL ::http://localhost:8080/login
 ##########   Retreiving from DB ##########
2021-06-30 15:32:05.561 DEBUG 9220 --- [nio-8080-exec-5] org.hibernate.SQL                        : select users0_.user_id as user_id1_0_, users0_.password as password2_0_, users0_.roles as roles3_0_, users0_.username as username4_0_ from users users0_ where users0_.username=?
 #######  Authorities  #######ADMIN
2021-06-30 15:32:05.580 DEBUG 9220 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to spring.security.spring.token.jwttoken.security.HelloWorldController#hello()
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER ####
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### method::GET
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### Servlet path::/hello
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### attibute names ::getAuthFilter.FILTERED
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URI ::/hello
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.AuthFilter     :  ##### INSIDE AUTH FILTER #### URL ::http://localhost:8080/hello
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ######  Inside Filter Test ####
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### method::GET
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### Servlet path::/hello
2021-06-30 15:32:05.580  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URI ::/hello
2021-06-30 15:32:05.592  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URL ::http://localhost:8080/hello
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ######  Inside Filter Test ####
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### method::GET
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### Servlet path::/hello
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URI ::/hello
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URL ::http://localhost:8080/hello
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ######  Inside Filter Test ####
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### method::GET
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### Servlet path::/hello
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URI ::/hello
2021-06-30 15:32:05.594  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.filter.FilterTest     :  ##### INSIDE FilterTest #### URL ::http://localhost:8080/hello
2021-06-30 15:32:05.597 DEBUG 9220 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet        : GET "/hello", parameters={}
2021-06-30 15:32:05.599 DEBUG 9220 --- [nio-8080-exec-6] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to spring.security.spring.token.jwttoken.security.HelloWorldController#hello()
2021-06-30 15:32:05.601  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.HelloWorldController  :  ########  INSIDE SIGN IN ########
 ##########   Retreiving from DB ##########
2021-06-30 15:32:05.602 DEBUG 9220 --- [nio-8080-exec-6] org.hibernate.SQL                        : select users0_.user_id as user_id1_0_, users0_.password as password2_0_, users0_.roles as roles3_0_, users0_.username as username4_0_ from users users0_ where users0_.username=?
 #######  Authorities  #######ADMIN
2021-06-30 15:32:05.604  INFO 9220 --- [nio-8080-exec-6] s.s.s.t.j.security.HelloWorldController  :  ########  INSIDE SIGN IN ######## Authentication completed
2021-06-30 15:32:05.607 DEBUG 9220 --- [nio-8080-exec-6] m.m.a.RequestResponseBodyMethodProcessor : Using 'text/html', given [text/html, application/xhtml+xml, image/avif, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json]
2021-06-30 15:32:05.608 DEBUG 9220 --- [nio-8080-exec-6] m.m.a.RequestResponseBodyMethodProcessor : Writing ["Hello World !!"]
2021-06-30 15:32:05.618 DEBUG 9220 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Completed 200 OK

从日志中可以看出,getAlreadyFilteredAttributeName将过滤器类标记为Filtered,但为什么它对同一个请求重复执行,因为根据文档,它不应该这样做。

请澄清我的疑惑。如果你能举出一个例子,我将非常感激。


StackOverflow:java - How spring guarantees single time execution of OncePerRequestFilter per request - Stack Overflow