[英]Spring boot filter called twice or not called at all
我實現了一個 customFilter,它將請求的 cookie 中的內容添加到其標頭中:
@Component
@Slf4j
public class MyCustomFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
.... some logic...
log.info("Sending request to next chain for validation..");
chain.doFilter(request, response);
log.info("Authentication completed sucessfully");
}
@Bean
// This method is needed to replace the default cookieFilter.json processor of tomcat that ignores the jwt cookieFilter.json
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
return tomcatServletWebServerFactory -> tomcatServletWebServerFactory.addContextCustomizers((TomcatContextCustomizer) context -> {
context.setCookieProcessor(new LegacyCookieProcessor());
});
}
}
我的 WebSecurityConfigurerAdapter 類:
@Configuration
public class AuthSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//configuring strategy
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.anyRequest().authenticated().and()
.oauth2ResourceServer().jwt().and();
http.csrf().disable();
http.addFilterBefore(new MyCustomFilter (), UsernamePasswordAuthenticationFilter.class);
http.exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint());
}
}
當我運行代碼並通過 postman/curl 發送請求時,我看到過濾器在
Sending request to next chain for validation..
Sending request to next chain for validation..
Authentication completed sucessfully
Authentication completed sucessfully
我找到了一些關於問題的帖子,並嘗試了以下解決方案:
發生這種情況是因為 spring 自動注冊了 bean,而我在配置方法中手動添加了過濾器。 因此,我刪除了在 configure() 方法中手動添加過濾器。 結果是根本沒有調用過濾器。
嘗試擴展OncePerRequestFilter
類,而不是實現過濾器接口。 這樣做了,但過濾器仍然觸發了兩次。
還嘗試刪除@Component
注釋並手動添加過濾器。 此外,我必須將CookieProcessor
bean 移至 Configuration 類。 之后出現的問題是應用程序無法啟動,因為以下錯誤:
引起:org.springframework.beans.BeanInstantiationException:無法實例化[org.springframework.web.servlet.HandlerMapping]:工廠方法'resourceHandlerMapping'拋出異常; 嵌套異常是 java.lang.IllegalStateException: No ServletContext set
我正在使用 spring-security 版本 5.3.3。
根據經驗,不要將@Bean
方法添加到@Component
類,因為它們的處理方式與@Configuration
類中的方法不同。 (見這個)。
@Bean
的代碼太復雜了。 創建並返回一個TomcatContextCustomizer
來進行修改。 您的代碼將導致循環引用,這將導致初始化錯誤。
將以下@Bean
方法添加到您的@SpringBootApplication
注釋類中
@Bean
public TomactContextCustomizer cookieProcessorCustomizer() {
return (context) -> context.setCookieProcessor(new LegacyCookieProcessor());
}
現在在您的Filter
中刪除@Component
或添加一個伴隨的FilterRegistrationBean
以防止將其添加到常規過濾器鏈中。 (Spring Boot 自動將所有檢測到的Filter
實例注冊到常規過濾器鏈)。
@Bean
public FilterRegistrationBean<MyFilter> myFilterRegistrationBean(MyFilter myFilter) {
FilterRegistrationBean<MyFilter> frb = new FilterRegistrationBean<>(myFilter);
frb.setEnabled(false);
return frb;
}
如果您刪除@Component
,則不需要上述代碼段,如果您不這樣做,則應在安全配置中重用掃描的MyFilter
實例。
@Configuration
public class AuthSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyFilter myFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
//configuring strategy
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.anyRequest().authenticated().and()
.oauth2ResourceServer().jwt().and();
http.csrf().disable();
http.addFilterBefore(myFilter, UsernamePasswordAuthenticationFilter.class);
http.exceptionHandling().authenticationEntryPoint(new AuthExceptionEntryPoint());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.