web-dev-qa-db-fra.com

Comment appliquer un filtre d'amorçage à ressort basé sur un modèle d'URL?

J'ai créé un filtre d'amorçage à ressort - implémente GenericFilterBean avec l'annotation @Component.

@Component 
public class MyAuthenticationFilter  extends GenericFilterBean {
...
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
...
}
}

Le filtre est automatiquement identifié par Spring Boot Framework et fonctionne correctement pour toutes les API REST. Je veux que ce filtre ne s'applique qu'à un certain chemin d'URL, tel que /api/secure/*, mais je ne trouve pas le bon chemin ... J'ai essayé @WebFilter mais cela n'a pas fonctionné. Je n’utilise pas la configuration XML ni l’initialiseur de servlet, mais uniquement les annotations.

Quelle serait la bonne façon de le faire fonctionner?

8
user1283002

Vous pouvez ajouter un filtre comme ceci:

@Bean
public FilterRegistrationBean someFilterRegistration() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("someFilter");
    registration.setOrder(1);
    return registration;
} 

@Bean(name = "someFilter")
public Filter someFilter() {
    return new SomeFilter();
}
15
Ulises

Il existe une autre option si vous pouvez étendre OncePerRequestFilter. Par exemple:

public class SomeFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // your filter logic ....
    }

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) {
        String path = request.getServletPath();
        return !path.startsWith("/api/secure/");
    }
}
3
vegemite4me

@ user1283002 Je pense qu'il est possible d'utiliser @WebFilter. Je suis tombé sur cet article article . Selon l'article (je n'ai pas essayé moi-même):

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter{
    // ..........
}

// and let Spring know to scan to find such @WebFilter annotation in your config
// class by using the @ServletComponentScan annotation like

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(MyApplication.class, args);
    }

   // ..........

}

EDIT: Après avoir lu plus de détails sur la documentation du @ServletComponentScan, je suis tombé sur un avertissement intéressant. 

La numérisation n’est effectuée que lors de l’utilisation d’un serveur Web intégré.

Ce qui signifie que lors du déploiement de notre application dans un conteneur Web (par exemple: Apache Tomcat), cette classe ne sera pas analysée par le cadre Spring et par conséquent, aucune configuration Spring (le cas échéant) ne sera appliquée.

S'il n'y a pas de configuration Spring à faire, vous pouvez continuer sans autre modification. Sinon, ajoutez simplement le scan @Component au filtre et assurez-vous que le paquet est dans le chemin de votre @ComponentScan annotation.

1
artemisian