web-dev-qa-db-fra.com

Empêcher Spring Boot d'enregistrer un filtre de servlet

J'ai une application Spring Boot WebMVC et un bean qui hérite de AbstractPreAuthenticatedProcessingFilter que j'ajoute explicitement à un endroit spécifique de la chaîne de filtrage Spring Security. Ma configuration Spring Security ressemble à ceci:

<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>

La configuration de sécurité fonctionne. Le problème est que, parce que la classe PreAuthenticationFilter hérite de AbstractPreAuthenticatedProcessingFilter, Spring Boot la traite comme un filtre de servlet à usage général et l'ajoute à la chaîne de filtres de servlet pour toutes les demandes. Je ne veux pas que ce filtre fasse partie de la chaîne de filtrage pour toutes les demandes. Je veux seulement qu'il fasse partie de la chaîne de filtres Spring Security spécifique que j'ai configurée. Existe-t-il un moyen d'empêcher Spring Boot d'ajouter automatiquement le bean preAuthenticationFilter à la chaîne de filtrage?

28
solarein

Par défaut, Spring Boot crée un FilterRegistrationBean pour chaque Filter dans le contexte d'application pour lequel un FilterRegistrationBean n'existe pas déjà. Cela vous permet de prendre le contrôle du processus d'enregistrement, y compris la désactivation de l'enregistrement, en déclarant votre propre FilterRegistrationBean pour le Filter. Pour votre PreAuthenticationFilter la configuration requise ressemblerait à ceci:

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

Vous pouvez également être intéressé par ce numéro Spring Boot qui explique comment désactiver l'enregistrement automatique des beans Filter et Servlet.

45
Andy Wilkinson

Si vous souhaitez annuler l'enregistrement de tous les filtres en même temps, voici mon astuce:

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

Un peu plus sur cette technique - ici .

6
dimafeng