Spring Boot ,Spring Security的Filter在Tomcat正常,部署在Weblogic 12c Filter順序出錯,導致攔截權限問題

Spring Boot使用main函數啓動或在tomcat中啓動時,Filter是按照正常的順序執行攔截,將工程打包爲war包,部署到weblogic上時,Filter執行順序錯亂,導致權限攔截出錯。

最近公司的一個項目使用Spring Boot開發,前期也做了技術評估,打包成war到Tomcat和Weblogic 12c上運行,靜態資源和RequestMapping訪問均正常,以爲萬事大吉,就開幹了,由於Spring Boot提供了main方式啓動,開發效率確實提高不少,所以團隊都使用這種方式開發,最近項目做的差不多了,要求測試,將工程打包爲war包,部署到weblogic上,問題來了,授權的url始終被一個攔截器優先攔截導致授權通不過,將war包放到Tomcat中,運行正常,百思不得其解。

抓捕問題步驟:

將出問題的Filter(我這裏爲MyFilterSecurityInterceptor)不addFilter到Spring Security的HttpSecurity中,打包部署到weblogic上,問題依舊,查看log日誌,還是進入到MyFilterSecurityInterceptor,oh my god.

於是將 @EnableWebSecurity(debug=true) debug打開,發現打印的Log 的 Security filter chain:  [] 確實沒有MyFilterSecurityInterceptor,可是爲啥還是進入到此MyFilterSecurityInterceptor,當時也沒多想,以爲weblogic的bug,上百度,google 查看了下,說需要重寫SpringBootServletInitializer的onStartup(ServletContext servletContext) ,查看了 SpringBootServletInitializer的方法,也不知道從何寫起,於是在源碼中打斷點追蹤代碼,發現只要是 實現了 Filter的類 ,並且 @Component 註解的,都進入 org.springframework.boot.web.servlet.AbstractFilterRegistrationBean.onStartup(ServletContext) 方法,被 FilterRegistration.Dynamic added = servletContext.addFilter(name, filter); addFilter添加到 servletContext中,難道系統對Filter的Bean默認註冊麼,經過搜索,果然是默認Filter自動註冊,spring boot官方文檔說明默認情況下對 @WebServlet@WebFilter, and @WebListener 以及 @Bean,@Component 這些只要是implements Filter的類,自動添加,默認的過濾路徑爲 /* 。


更改方式,

去掉 @Component

        MyFilterSecurityInterceptor myFilterSecurityInterceptor = new MyFilterSecurityInterceptor();
        myFilterSecurityInterceptor.setAccessDecisionManager(myAccessDecisionManager);
        myFilterSecurityInterceptor.setSecurityMetadataSource(securityMetadataSourceService);
        httpSecurity
        //添加JWT filter
        .addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
        //添加 攔截權限 filter
        .addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);

通過new 方式,即可解決此問題。


其他解決方式:Spring Boot對Servlet,Filter提供了相應的註冊類,可以使用 FilterRegistrationBean 來講進行Filter的精細化配置:

官方給出示例:

@Bean
public FilterRegistrationBean registration(MyFilter filter) {
    FilterRegistrationBean registration = new FilterRegistrationBean(filter);
    registration.setEnabled(false);
    return registration;
}

看來真是得好好看官方文檔啊,不瞭解Spring Boot,還真是很容易入坑。

將此問題記下,以免再次犯錯誤。


參考資料:

Spring Boot Document

Spring Boot: 取消Filter自動註冊

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章