Подтвердить что ты не робот

Предотвращение Spring Загрузка с регистрацией фильтра сервлета

У меня есть приложение для загрузки WebMVC Spring и bean, которое наследуется от AbstractPreAuthenticatedProcessingFilter, которое я явно добавляю к определенному месту в цепочке фильтров Spring. Моя конфигурация безопасности 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>

Работает конфигурация безопасности. Проблема состоит в том, что класс PreAuthenticationFilter наследуется от AbstractPreAuthenticatedProcessingFilter, Spring Boot рассматривает его как фильтр сервлетов общего назначения и добавляет его в цепочку фильтров сервлетов для всех запросов. Я не хочу, чтобы этот фильтр был частью цепочки фильтров для всех запросов. Я хочу, чтобы он был частью определенной цепочки фильтров безопасности Spring, которую я настроил. Есть ли способ предотвратить загрузку Spring Boot из автоматического добавления preAuthenticationFilter bean в цепочку фильтров?

4b9b3361

Ответ 1

По умолчанию Spring Boot создает FilterRegistrationBean для каждого Filter в контексте приложения, для которого FilterRegistrationBean еще не существует. Это позволяет вам контролировать процесс регистрации, включая отключение регистрации, объявив свой FilterRegistrationBean для Filter. Для вашей PreAuthenticationFilter требуемая конфигурация будет выглядеть так:

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

Вы также можете быть заинтересованы в этой Spring проблеме загрузки, в которой обсуждается, как отключить автоматическую регистрацию Filter и Servlet beans.

Ответ 2

Если вы хотите отменить регистрацию всех фильтров за один раз здесь, мой трюк:

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);
                });
    }
}

Немного больше об этой технике - здесь.