[英]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.