简体   繁体   English

防止Spring Boot注册servlet过滤器

[英]Prevent Spring Boot from registering a servlet filter

I have a Spring Boot WebMVC application, and a bean that inherits from AbstractPreAuthenticatedProcessingFilter which I am explicitly adding to a specific spot in the Spring Security filter chain.我有一个 Spring Boot WebMVC 应用程序和一个继承自 AbstractPreAuthenticatedProcessingFilter 的 bean,我明确将其添加到 Spring 安全过滤器链中的特定位置。 My Spring Security configuration looks like this:我的 Spring 安全配置如下所示:

<http pattern="/rest/**">
  <intercept-url pattern="/**" access="ROLE_USER"/>
  <http-basic/>
  <custom-filter after="BASIC_AUTH_FILTER" ref="preAuthenticationFilter"/>
</http>

<beans:bean id="preAuthenticationFilter" class="a.b.PreAuthenticationFilter">
  <beans:property name="authenticationManager" ref="customAuthenticationManager"/>
</beans:bean>

The security configuration works.安全配置有效。 The problem is, because the PreAuthenticationFilter class inherits from AbstractPreAuthenticatedProcessingFilter, Spring Boot treats it as a general purpose servlet filter and is adding it to the servlet filter chain for all requests.问题是,因为 PreAuthenticationFilter class 继承自 AbstractPreAuthenticatedProcessingFilter,Spring Boot 将其视为通用 servlet 过滤器,并将其添加到所有请求的 servlet 过滤器链中。 I don't want this filter to be part of the filter chain for all requests.我不希望此过滤器成为所有请求的过滤器链的一部分。 I only want it to be part of the specific Spring Security filter chain that I've configured.我只希望它成为我配置的特定 Spring 安全过滤器链的一部分。 Is there a way to prevent Spring Boot from automatically adding the preAuthenticationFilter bean to the filter chain?有没有办法阻止 Spring Boot 自动将 preAuthenticationFilter bean 添加到过滤器链?

By default Spring Boot creates a FilterRegistrationBean for every Filter in the application context for which a FilterRegistrationBean doesn't already exist. 默认情况下,Spring Boot会为应用程序上下文中的每个Filter创建一个FilterRegistrationBean ,而FilterRegistrationBean尚不存在。 This allows you to take control of the registration process, including disabling registration, by declaring your own FilterRegistrationBean for the Filter . 这允许您通过为Filter声明自己的FilterRegistrationBean来控制注册过程,包括禁用注册。 For your PreAuthenticationFilter the required configuration would look like this: 对于PreAuthenticationFilter ,所需的配置如下所示:

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

You may also be interested in this Spring Boot issue which discusses how to disable the automatic registration of Filter and Servlet beans. 您可能还对此Spring Boot问题感兴趣, 该问题讨论了如何禁用FilterServlet bean的自动注册。

If you want to unregister all filters at one time here's my trick: 如果您想一次取消注册所有过滤器,这是我的诀窍:

public class DefaultFiltersBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf)
            throws BeansException {
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf;

        Arrays.stream(beanFactory.getBeanNamesForType(javax.servlet.Filter.class))
                .forEach(name -> {

                    BeanDefinition definition = BeanDefinitionBuilder
                            .genericBeanDefinition(FilterRegistrationBean.class)
                            .setScope(BeanDefinition.SCOPE_SINGLETON)
                            .addConstructorArgReference(name)
                            .addConstructorArgValue(new ServletRegistrationBean[]{})
                            .addPropertyValue("enabled", false)
                            .getBeanDefinition();

                    beanFactory.registerBeanDefinition(name + "FilterRegistrationBean",
                            definition);
                });
    }
}

A bit more about this technique - here . 关于这种技术的更多信息 - 这里

If you need to disable registering 2 filters(like i did), include a name for the bean(so that they do not override):如果您需要禁用注册 2 个过滤器(就像我所做的那样),请包含 bean 的名称(这样它们就不会覆盖):

@Bean(name = "filterRegistrationBean1")
public FilterRegistrationBean<YourFilter1> registration(YourFilter1 f1) {
    FilterRegistrationBean<YourFilter1> registration = new FilterRegistrationBean<>(f1);
    registration.setEnabled(false);
    return registration;
}

@Bean(name = "filterRegistrationBean2")
public FilterRegistrationBean<YourFilter2> registration(YourFilter2 f2) {
    FilterRegistrationBean<YourFilter2> registration = new FilterRegistrationBean<>(f2);
    registration.setEnabled(false);
    return registration;
}

I use aop to do that, use around pointcut to joincut your filter, manully invode我使用 aop 来做到这一点,使用 around pointcut 来连接你的过滤器,手动调用
filterChain.doFilter(request, response)

@Aspect
@Component
public class AspectDemo {

    @Around(value = "com.xxx.pointcut01()")
    public void around01(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("[Aspect-around01] start");

        ServletRequest request = (ServletRequest)Arrays.asList(
                ((MethodInvocationProceedingJoinPoint) joinPoint).getArgs()
        ).get(0);

        ServletResponse response = (ServletResponse)Arrays.asList(
                ((MethodInvocationProceedingJoinPoint) joinPoint).getArgs()
        ).get(1);


        FilterChain filterChain = (FilterChain)Arrays.asList(
                ((MethodInvocationProceedingJoinPoint) joinPoint).getArgs()
        ).get(2);

        filterChain.doFilter(request, response);

        //do not execute origin doFilter() method
        //joinPoint.proceed();
        System.out.println("[Aspect-around01] end");

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 防止Spring Boot注册Spring Security过滤器之一 - Prevent Spring Boot from registering one of Spring Security filter Servlet过滤器作为组件Spring Boot - Servlet Filter as Component Spring Boot 在Spring Boot应用程序中添加Servlet过滤器 - Add a Servlet Filter in a Spring Boot application 在Spring Boot中为Servlet配置添加过滤器 - Adding a filter to the Servlet configuration in Spring Boot 如何使用Spring Boot Filter Registration Bean将依赖项注入Servlet过滤器? - How to Inject Dependencies into a Servlet Filter with Spring Boot Filter Registration Bean? 刚刚从Spring Boot 2.7.4升级到Spring Boot 3.0.0,导致报错 Caused by: java.lang.NoClassDefFoundError: javax.servlet.Filter - Just upgraded from Spring Boot 2.7.4 to Spring Boot 3.0.0, caused error Caused by: java.lang.NoClassDefFoundError: javax.servlet.Filter javax.servlet.ServletException:过滤器执行在Spring Boot中引发了异常 - javax.servlet.ServletException: Filter execution threw an exception in spring boot 在Spring Boot中添加servlet过滤器时没有默认构造函数 - No default constructor when adding servlet filter in Spring Boot Spring boot:无法加载缓存项:javax/servlet/Filter - Spring boot : Unable to load cache item: javax/servlet/Filter 春季启动:将Servlet过滤器应用于除一条之外的所有路由 - Spring-boot: Apply Servlet Filter to all routes except one
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM