web-dev-qa-db-fra.com

Quel est l'intérêt de DelegatingFilterProxy de Spring MVC?

Je vois ceci dans web.xml De mon application Spring MVC:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

J'essaie de comprendre pourquoi c'est là et si c'est vraiment nécessaire.

J'ai trouvé cette explication dans la documentation du printemps mais cela ne m'aide pas à en comprendre le sens:

Il semble suggérer que ce composant est la "colle" entre les servlets définis dans web.xml Et les composants définis dans le Spring applicationContext.xml.

7.1 DelegatingFilterProxy

Lorsque vous utilisez des filtres de servlet, vous devez évidemment les déclarer dans votre web.xml, Sinon ils seront ignorés par le conteneur de servlet. Dans Spring Security, les classes de filtre sont également des beans Spring définis dans le contexte de l'application et permettent donc de tirer parti des riches fonctions d'injection de dépendance et des interfaces de cycle de vie de Spring. DelegatingFilterProxy de Spring fournit le lien entre web.xml Et le contexte de l'application.

En utilisant DelegatingFilterProxy, vous verrez quelque chose comme ceci dans le fichier web.xml:

<filter>
  <filter-name>myFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>myFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Notez que le filtre est en réalité un DelegatingFilterProxy et non la classe qui implémentera réellement la logique du filtre. Ce que DelegatingFilterProxy fait, c'est déléguer les méthodes du filtre à un bean obtenu à partir du contexte de l'application Spring. Cela permet au bean de bénéficier du support du cycle de vie du contexte de l'application Web Spring et de la flexibilité de la configuration. Le bean doit implémenter javax.servlet.Filter Et doit avoir le même nom que celui de l'élément filter-name. Lisez le Javadoc pour DelegatingFilterProxy pour plus d'informations.

Donc, si je retire ceci de mon web.xml, Que se passera-t-il? Mes servlets ne pourront pas communiquer avec le conteneur Spring? **

113
Thomas

Il y a une sorte de magie ici, mais au final, tout est un programme déterministe.

DelegatingFilterProxy est un filtre comme expliqué ci-dessus, dont le but est " ==) déléguer à un ressort bean géré qui implémente l’interface Filter ", c’est-à-dire qu’il trouve un bean (" bean cible "ou" délégué ") dans votre contexte d’application Spring et l’appelle. Comment est-ce possible? Comme ce bean implémente javax.servlet.Filter, sa méthode doFilter est appelée.

Quel haricot s'appelle? DelegatingFilterProxy "Prend en charge un" targetBeanName "[...], spécifiant le nom du bean cible dans le contexte de l'application Spring."

Comme vous l'avez vu dans votre fichier web.xml, le nom du bean est " springSecurityFilterChain" .

Ainsi, dans le contexte d’une application Web, un filtre instancie un bean appelé "springSecurityFilterChain" dans votre contexte d’application, puis le lui délègue via la méthode doFilter ().

N'oubliez pas que le contexte de votre application est défini avec TOUS LES fichiers XML (APPLICATION-CONTEXT). Par exemple: applicationContext.xml ET applicationContext-security.xml.

Alors essayez de trouver un haricot appelé "springSecurityFilterChain" dans ce dernier ...

... et probablement impossible (par exemple, si vous avez suivi un tutoriel ou si vous avez configuré la sécurité à l'aide de Roo)

Voici la magie: il y a un nouvel élément pour configurer la sécurité , quelque chose comme

<http auto-config="true" use-expressions="true"> 

comme il est permis par http://www.springframework.org/schema/security/spring-security-3.0.xsd , fera l'affaire.

Lorsque Spring charge le contexte d'application à l'aide de fichiers XML, s'il trouve un élément, il tente de configurer la sécurité HTTP, c'est-à-dire une pile de filtres et des URL protégées, puis d'enregistrer le FilterChainProxy nommé "springSecurityFilterChain".

Vous pouvez également définir le haricot de la manière classique, à savoir:

<beans:bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">

Mais c'est moins recommandé, car vous devez faire beaucoup de configuration (tous les filtres que vous allez utiliser. Et il y en a plus d'une douzaine).

123
jbbarquero

Savez-vous ce qu'est un Servlet Filtre et comment ça marche? C'est un élément très utile de la spécification Servlet, qui nous permet d'appliquer des concepts de type AOP à la gestion des demandes HTTP. De nombreux frameworks utilisent des implémentations de filtre pour différentes choses, et il n'est pas rare de trouver des implémentations personnalisées car ils sont très simples à écrire et utiles. Dans une application Spring, la plupart des choses que votre application peut faire sont dans vos haricots Spring. Cependant, une instance de filtre est contrôlée par le conteneur de servlet. Le conteneur l'instancie, l'initialise et le détruit. Cependant, la spécification Servlet ne requiert aucune sorte d'intégration Spring. Vous disposez donc d'un concept très utile (filtres), sans aucun moyen pratique de le lier à votre application Spring et aux beans qui font le travail.

Entrez le DelegatingFilterProxy. Vous écrivez une implémentation Filter et en faites un bean Spring, mais au lieu d'ajouter votre propre classe Filter au fichier web.xml, vous utilisez DelegatingFilterProxy et lui donnez le nom du bean de votre filtre dans le contexte Spring. (Si vous ne fournissez pas explicitement un nom, il utilise le "nom-filtre".) Ensuite, au moment de l'exécution, DelegatingFilterProxy gère la complexité de la recherche de la véritable implémentation - celle que vous avez écrite et configurée dans Spring - et du traitement de ses demandes de routage. . Ainsi, à l'exécution, c'est comme si vous aviez répertorié votre filtre dans le fichier web.xml, mais vous bénéficiez de l'avantage de pouvoir le câbler comme n'importe quel autre bean Spring.

Si vous retirez ce mappage de filtre de votre fichier web.xml, tout continuera à fonctionner, mais aucune de vos URL ne sera sécurisée. (Cela suppose que le nom "springSecurityFilterChain" décrit précisément ce qu'il fait.) En effet, ce mappage filtre toutes les demandes entrantes et les transfère à un filtre de sécurité défini dans votre contexte Spring.

66
Ryan Stewart

Que sont les filtres de servlet?

Les filtres de servlet sont, en général, un concept WebApp Java. Vous pouvez avoir des filtres de servlet dans n’importe quelle application Web, que vous utilisiez ou non le framework Spring dans votre application.

Ces filtres peuvent intercepter les demandes avant qu'elles n'atteignent le servlet cible. Vous pouvez implémenter des fonctionnalités communes, telles que l'autorisation, dans les filtres de servlet. Une fois implémenté, vous pouvez configurer le filtre dans votre fichier web.xml pour qu’il soit appliqué à un servlet spécifique, à des modèles d’URL de requête spécifiques ou à tous les modèles d’URL.

Où les filtres de servlet sont utilisés?

Les applications Web modernes peuvent avoir des dizaines de tels filtres. Des tâches telles que l'autorisation, la mise en cache, la gestion de session ORM et l'injection de dépendances sont souvent implémentées à l'aide d'un filtre de servlet. Tous ces filtres doivent être enregistrés dans web.xml.

Instanciation des filtres de servlet - sans framework Spring

Votre conteneur de servlets crée des instances de filtres déclarés dans web.xml Et les appelle à des moments appropriés (c'est-à-dire lors du traitement des demandes de servlets). Maintenant, si vous êtes comme la plupart des fans d'injection de dépendance (DI), vous diriez probablement que la création d'instances est ce que mon framework (Spring) fait de mieux. Est-ce que je ne peux pas créer mes filtres de servlet avec Spring afin qu'ils soient compatibles avec tous les bienfaits du DI?

DelegatingFilterProxy, afin que Spring crée vos instances de filtre

C’est là que DelegatingFilterProxy intervient. DelegatingFilterProxy est une impelmentation de l’interface javax.servlet.Filter Fournie par Spring Framework. Une fois que vous avez configuré DelegatingFilterProxy dans web.xml, vous pouvez déclarer les beans réels qui effectuent le filtrage dans votre configuration de printemps. De cette façon, Spring crée les instances de beans qui effectuent le filtrage, et vous pouvez utiliser DI pour configurer ces beans.

Notez que vous n'avez besoin que d'une seule déclaration DelegatingFilterProxy dans web.xml, Mais plusieurs filtres beans doivent être chaînés dans le contexte de votre application.

41
Tahir Akhtar

Le fait est que les filtres de servlet sont gérés par le conteneur de servlets et non par le printemps. Et vous devrez peut-être injecter des composants de ressort dans vos filtres.

Donc, si vous avez besoin de quelque chose comme:

public class FooFilter {

    @Inject
    private FooService service;

    public void doFilter(....) { .. }

}

alors vous avez besoin du proxy de filtrage délégué.

14
Bozho

Vous avez raison au sujet de la colle. Comme écrit dans JavaDocs de FilterChainProxy :

FilterChainProxy est lié à la chaîne de filtres du conteneur de servlets en ajoutant une déclaration Spring DelegatingFilterProxy standard dans le fichier web.xml de l'application.

Veuillez consulter la section FIlterChainProxy du blog Derrière l’espace de noms de sécurité Spring pour une excellente explication.

1
Ritesh

Cela faisait longtemps mais j'avais la même question et j'ai trouvé ceci: https://www.javacodegeeks.com/2013/11/spring-security-hind-the-scenes.html

J'ai essayé de lancer mon projet de sécurité Spring en supprimant le filtre en question et en l'ajoutant. Ce que j’ai trouvé, c’est que si nous ajoutons le filtre, l’appel sera alors redirigé vers la page de connexion requise, telle que définie dans la configuration de sécurité printanière.

Donc, accepter la réponse de @ Ryan.

0
OutOfMind

J'ai été perplexe par "springSecurityFilterChain" dans web.xml et j'ai trouvé cette réponse dans le document de sécurité de springframework:

Le <http> element encapsule la configuration de sécurité pour la couche Web de votre application. > Il crée un bean FilterChainProxy nommé "springSecurityFilterChain" qui conserve la pile de> filtres de sécurité qui constituent la configuration de la sécurité Web [19]. Certains filtres principaux sont toujours créés et d'autres seront ajoutés à la pile en fonction des attributs des éléments enfants présents. Les positions des filtres standard sont fixes (voir la table des ordres de filtres dans> l'introduction du namespace), ce qui supprime une source commune d'erreurs avec les versions précédentes du framework> lorsque les utilisateurs devaient configurer la chaîne de filtres de manière explicite dans le beanFilterChainProxy. Bien sûr, vous pouvez toujours le faire si vous avez besoin d'un contrôle total de la configuration.

Voici le lien http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html

0
Janet