Vue d'ensemble et besoin de DelegatingFilterProxy au printemps

1. Vue d'ensemble

Le DelegatingFilterProxy est un filtre de servlet qui permet de contrôler le passage de filtre des classes qui ont accès au contexte d'application Spring. Spring Security s'appuie fortement sur cette technique.

Dans ce tutoriel, nous allons le couvrir en détail.

2. DelegatingFilterProxy

Le Javadoc pour DelegatingFilterProxy indique qu'il s'agit d'un

Proxy pour un filtre de servlet standard, déléguant à un bean géré par Spring qui implémente l'interface Filter.

Lorsque vous utilisez des filtres de servlet, nous devons évidemment les déclarer comme classe de filtre dans notre configuration Java ou web.xml , sinon le conteneur de servlet les ignorera. DelegatingFilterProxy de Spring fournit le lien entre web.xml et le contexte de l'application.

2.1. Fonctionnement interne de DelegatingFilterProxy

Voyons comment DelegatingFilterProxy transfère le contrôle à notre bean Spring.

Lors de l'initialisation, DelegatingFilterProxy récupère le nom du filtre et récupère le bean portant ce nom à partir du contexte d'application Spring. Ce bean doit être de type javax.Servlet.Filter, c'est-à-dire un filtre de servlet «normal». Les demandes entrantes seront ensuite transmises à ce bean filtre.

En bref, la méthode doFilter () de DelegatingFilterProxy déléguera tous les appels à un bean Spring, ce qui nous permettra d'utiliser toutes les fonctionnalités de Spring dans notre bean filtre.

Si nous utilisons une configuration basée sur Java, notre enregistrement de filtre dans ApplicationInitializer sera défini comme:

@Override protected javax.servlet.Filter[] getServletFilters() { DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy(); delegateFilterProxy.setTargetBeanName("applicationFilter");   return new Filter[]{delegateFilterProxy}; }

Si nous utilisons XML, alors, dans le fichier web.xml :

 applicationFilter org.springframework.web.filter.DelegatingFilterProxy 

Cela signifie que toute demande peut être faite pour passer à travers le filtre défini comme Spring bean avec le nom applicationFilter .

2.2. Besoin de DelegatingFilterProxy

DelegatingFilterProxy est une classe du module Web de Spring. Il fournit des fonctionnalités permettant de faire passer les appels HTTP à travers des filtres avant d'atteindre la destination réelle. À l'aide de DelegatingFilterProxy, une classe implémentant l' interface javax.Servlet.Filter peut être câblée dans la chaîne de filtres.

À titre d'exemple, Spring Security utilise DelegatingFilterProxy pour pouvoir tirer parti des fonctionnalités d'injection de dépendances de Spring et des interfaces de cycle de vie pour les filtres de sécurité.

DelegatingFilterProxy exploite également l'appel de filtres spécifiques ou multiples selon les chemins d'URI de demande en fournissant la configuration dans le contexte d'application de Spring ou dans web.xml.

3. Création d'un filtre personnalisé

Comme décrit ci-dessus, DelegatingFilterProxy est un filtre de servlet lui-même qui délègue à un bean géré par Spring spécifique qui implémente l' interface de filtre .

Dans les prochaines sections, nous allons créer un filtre personnalisé et le configurer à l'aide d'une configuration Java et XML.

3.1. Classe de filtre

Nous allons créer un filtre simple qui enregistre les informations de demande avant que la demande ne continue.

Commençons par créer une classe de filtre personnalisée:

@Component("loggingFilter") public class CustomFilter implements Filter { private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class); @Override public void init(FilterConfig config) throws ServletException {        // initialize something } @Override public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; LOGGER.info("Request Info : " + req); chain.doFilter(request, response); } @Override public void destroy() { // cleanup code, if necessary } } 

CustomFilter implémente javax.Servlet.Filter . Cette classe a une annotation @Component à enregistrer en tant que Spring bean dans le contexte de l'application. De cette façon, la classe DelegatingFilterProxy peut trouver notre classe de filtre lors de l'initialisation de la chaîne de filtres.

Notez que le nom du bean Spring doit être le même que la valeur du nom du filtre fourni lors de l'enregistrement du filtre personnalisé dans la classe ApplicationInitializer ou dans web.xml ultérieurement car la classe DelegatingFilterProxy recherchera le bean filtre avec l'exact même nom dans le contexte de l'application.

S'il ne trouve pas de bean avec ce nom, il lèvera une exception au démarrage de l'application.

3.2. Configuration du filtre via la configuration Java

Pour enregistrer un filtre personnalisé à l'aide de la configuration Java, nous devons remplacer la méthode getServletFilters () de AbstractAnnotationConfigDispatcherServletInitializer :

public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // some other methods here @Override protected javax.servlet.Filter[] getServletFilters() { DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy(); delegateFilterProxy.setTargetBeanName("loggingFilter");   return new Filter[]{delegateFilterProxy}; } }

3.3. Configuration du filtre via web.xml

Voyons à quoi ressemble la configuration du filtre dans web.xml :

 loggingFilter org.springframework.web.filter.DelegatingFilterProxy   loggingFilter /* 

L' argument de classe de filtre est de type DelegatingFilterProxy et non de la classe de filtre que nous avons créée. Si nous exécutons ce code et frappons une URL, la méthode doFilter () du CustomFilter sera exécutée et affichera les détails de la demande dans le fichier journal.

4. Conclusion

Dans cet article, nous avons décrit le fonctionnement de DelegatingFilterProxy et son utilisation.

Spring Security fait un usage intensif de DelegatingFilterProxy pour sécuriser les appels et les ressources de l'API Web contre les accès non autorisés.

Le code source est disponible à l'adresse over sur GitHub.