解決Spring Security自定義filter重復執行問題


今天做項目的時候,發現每次攔截器日志都會打兩遍,很納悶,懷疑是Filter被執行了兩遍。結果debug之后發現還真是!記錄一下這個神奇的BUG!

問題描述

項目中使用的是Spring-security作為權限框架,然后做了一個JwtAuthenticationTokenFilter作為攔截器攔截請求,校驗Token,但是每次請求都會打兩遍日志。下面是精簡的源代碼:

自定義的Filter類

@Slf4j
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(
            HttpServletRequest request,
            HttpServletResponse response,
            FilterChain chain) throws ServletException, IOException {
        //...省略
        //打出兩遍日志的地方
        log.info("User:{} request path:{}, method:{}, param:{}", username, request.getServletPath(),
                request.getMethod(), request.getParameterMap() == null ? null : OBJECT_MAPPER.writeValueAsString(request.getParameterMap()));
        //...省略
        chain.doFilter(request, response);
    }
}

WebSecurityConfig配置類

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    //...省略
    @Bean
    public JwtAuthenticationTokenFilter authenticationTokenFilterBean() throws Exception {
        return new JwtAuthenticationTokenFilter();
    }
    
        @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        //...省略
        //把JwtAuthenticationTokenFilter加入到RememberMeAuthenticationFilter之前
        httpSecurity.addFilterBefore(authenticationTokenFilterBean(), RememberMeAuthenticationFilter.class);
    }
    //...省略
}

請求日志如下:

問題解決

把自定義FilterJwtAuthenticationTokenFilter@Component取消掉就可以了,不讓它被Spring容器管理。

原因

在spring容器托管的OncePerRequestFilter的bean,都會自動加入到servlet的filter chain,而上面的定義,還額外把filter加入到了spring security的
ememberMeAuthenticationFilter之前。而spring security也是一系列的filter,在mvc的filter之前執行。因此在鑒權通過的情況下,就會先后各執行一次。

參考資料

解決spring security自定義filter重復執行問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM