Java Spring引导筛选器已调用两次或根本未调用
我实现了一个customFilter,它将请求Cookie中的内容添加到其标题中:Java Spring引导筛选器已调用两次或根本未调用,java,spring,spring-boot,spring-security,Java,Spring,Spring Boot,Spring Security,我实现了一个customFilter,它将请求Cookie中的内容添加到其标题中: @Component @Slf4j public class MyCustomFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
@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());
});
}
}
当我运行代码并通过postman/curl发送请求时,我看到过滤器在
Sending request to next chain for validation..
Sending request to next chain for validation..
Authentication completed sucessfully
Authentication completed sucessfully
我找到了一些关于这个问题的帖子,并尝试了以下解决方案:
OncePerRequestFilter
类,而不是实现过滤器接口。这样做了,但过滤器仍然触发了两次
@组件
批注并手动添加筛选器。此外,我必须将CookieProcessor
bean移动到配置类。之后出现的问题是,由于以下错误,应用程序无法启动:
原因:org.springframework.beans.beans实例化异常:未能实例化[org.springframework.web.servlet.HandlerMapping]:工厂方法“resourceHandlerMapping”引发异常;嵌套异常为java.lang.IllegalStateException:未设置ServletContext
我使用的是spring安全版本5.3.3。根据经验,不要将
@Bean
方法添加到@Component
类中,因为这些方法的处理方式与@Configuration
类中的不同。(见附件)
@Bean
中的代码太复杂。创建并返回一个TomcatContextCustomizer
来进行修改。您的代码将导致循环引用,这将导致初始化错误
将以下@Bean
方法添加到@springbootplication
注释类
@Bean
公共TomactContextCustomizer cookieProcessorCustomizer(){
return(context)->context.setCookieProcessor(新的LegacyCookieProcessor());
}
现在,在您的过滤器中
删除@组件
或添加一个Accomping过滤器注册bean
,以防止它被添加到常规过滤器链中。(Spring Boot自动将所有检测到的过滤器实例注册到常规过滤器链)
@Bean
公共过滤器注册Bean myFilterRegistrationBean(MyFilter MyFilter){
FilterRegistrationBean frb=新的FilterRegistrationBean(myFilter);
frb.setEnabled(假);
返回frb;
}
如果删除@组件
,则不需要上述代码段,如果不删除,则应在安全配置中重新使用扫描的MyFilter
实例
@配置
公共类AuthSecurityConfig扩展了WebSecurity配置适配器{
@自动连线
私人MyFilter MyFilter;
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
//配置策略
http.sessionManagement()
.sessionCreationPolicy(sessionCreationPolicy.STATELESS)和()
.授权请求()
.anyRequest().authenticated()和()
.oauth2ResourceServer().jwt()和();
http.csrf().disable();
addFilterBefore(myFilter,UsernamePasswordAuthenticationFilter.class);
http.exceptionHandling().authenticationEntryPoint(新的AuthExceptionEntryPoint());
}
}
移除@组件
。它目前是普通筛选链和安全筛选链的一部分,因此执行两次(也注册两次)。@Bean
方法应位于@Configuration
类上,而不是此@组件上。我将Bean移动到配置中,并得到以下错误:原因:org.springframework.beans.beanstantiationexception:未能实例化[org.springframework.web.servlet.HandlerMapping]:工厂方法“resourceHandlerMapping”引发异常;嵌套异常为java.lang.IllegalStateException:No ServletContext集合返回一个TomcatContextCustomizer
,并且不添加它。你把事情弄得太复杂了。我使用了以下代码,但仍然得到相同的错误:public TomcatContextCustomizer CookieProcessor Customizer(){return context->context.setCookieProcessor(new LegacyCookieProcessor());}首先,感谢你的清晰解释。我删除了@Component注释,因此我没有传递注入的bean,而是创建了一个过滤器的新实例,并在(..)之前传递给addFilterBefore。我试图运行它,但得到了相同的错误:(您还需要TomcatContextCustomizer
否则将不会注册LegacyCookieProcessor
。我没有编写它,但我将TomcatContextCustomizer Bean添加到我的@ConfigurationOn类中。当我在没有TomcatContextCustomizer方法的情况下运行代码时,spring应用程序启动,但我的Cookie被忽略stomizer,由于我前面提到的上下文错误,spring应用程序无法启动。解决方案将TomcatContextCustomizer移动到另一个@Configuration类,而不是将其保留在扩展WebSecurityConfigureAdapter的类中。感谢所有帮助!!