Spring MVCのDelegatingFilterProxyのポイントは何ですか?


120

私のSpring MVCアプリにこれが見られますweb.xml

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

なぜそこにあるのか、そしてそれが実際に必要かどうかを理解しようとしています。

私はこの説明をSpringドキュメントで見つけましたが、それは私がそれを理解するのに役立ちません:

このコンポーネントは、で定義されたサーブレットweb.xmlとSpringで定義されたコンポーネントの間の「接着剤」であることが示唆されているようapplicationContext.xmlです。

7.1 DelegatingFilterProxy

サーブレットフィルターを使用する場合は、明らかにそれらをで宣言する必要がありますweb.xml。そうしないと、サーブレットコンテナーによって無視されます。Spring Securityでは、フィルタークラスはアプリケーションコンテキストで定義されたSpring Beanでもあるため、Springの豊富な依存性注入機能とライフサイクルインターフェースを利用できます。SpringはとアプリケーションコンテキストDelegatingFilterProxy間のリンクを提供しweb.xmlます。

DelegatingFilterProxyを使用すると、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>

フィルターは実際にはDelegatingFilterProxyであり、実際にフィルターのロジックを実装するクラスではないことに注意してください。どのようなDelegatingFilterProxy行いは、Springアプリケーションコンテキストから取得された豆を通過フィルタのメソッドを委譲です。これにより、BeanはSpring Webアプリケーションのコンテキストライフサイクルサポートと構成の柔軟性を活用できます。Beanは実装javax.servlet.Filterする必要があり、filter-name要素と同じ名前である必要があります。詳細については、DelegatingFilterProxyJavadocを参照してください

それで、これをから取り出した場合web.xml、どうなりますか?サーブレットがSpringコンテナと通信できなくなりますか?**

回答:


127

ここにはある種の魔法がありますが、結局のところ、すべてが確定的なプログラムです。

DelegatingFilterProxyは、その目標」され、それは前述したように、フィルタ、であるSpring管理Beanに委任することが実装Filterインタフェースされ、それは、Springアプリケーションに豆(「ターゲットBean」または「代理人」)を見つけました」コンテキストを呼び出します。どのようにして可能ですか?このBeanはjavax.servlet.Filterを実装しているため、そのdoFilterメソッドが呼び出されます。

どのBeanが呼び出されますか?DelegatingFilterProxyは、「SpringアプリケーションコンテキストでのターゲットBeanの名前を指定して、「targetBeanName」[...]をサポートします。」

web.xmlでBeanの名前が「springSecurityFilterChain」であることを確認したようにです。

したがって、Webアプリケーションのコンテキストでは、Filterはアプリケーションコンテキストで「springSecurityFilterChain」と呼ばれるBeanをインスタンス化し、doFilter()メソッドを介してそれにデリゲートします。

アプリケーションコンテキストは、すべてのAPPLICATION-CONTEXT(XML)ファイルで定義されることに注意してください。たとえば、applicationContext.xml AND applicationContext-security.xml。

したがって、「springSecurityFilterChain」というBean見つけてみてください後者の ...

...そしておそらくできない(たとえば、チュートリアルを実行した場合、またはRooを使用してセキュリティを構成した場合)

ここでは魔法は次のとおりです。セキュリティを設定するための新たな要素があります、のようなもの

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

http://www.springframework.org/schema/security/spring-security-3.0.xsdで許可されているためで、うまくいきます。

SpringがXMLファイルを使用してアプリケーションコンテキストをロードするときに、要素が見つかった場合、HTTPセキュリティ、つまりフィルタースタックと保護されたURLを設定し、「springSecurityFilterChain」という名前のFilterChainProxyを登録しようとします。

または、クラシックな方法でBeanを定義することもできます。

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

ただし、多くの構成を行う必要があるため、あまりお勧めしません(使用するすべてのフィルターです。また、それらのフィルターは12個以上あります)。


「applicationContext-security.xml AND applicationContext-security.xml」は同じファイル名です。
musiKk 2014年

musiKkに感謝(投稿を直接編集できると思います)
jbbarquero 2014年

これは私がずっと探していて、私のために物事を片付けたことの説明でした。
user871611 2014年

@jbbarquero:その通りですが、正しいバージョンがどうあるべきかわかりませんでした。意図せずに意味を変えないように、元の作者が修正するようにしておきます。
musiKk 14

OK。とにかく、私は私の応答を改善するためにあなたの多くの助けに感謝します。ありがとう、musiKk
jbbarquero

73

サーブレットフィルターとは何か、どのように機能するか知っていますか。これはサーブレット仕様の非常に便利な部分であり、AOPのような概念をHTTPリクエストのサービスに適用することができます。多くのフレームワークはさまざまな目的でFilter実装を使用しますが、それらのカスタム実装が非常に簡単に記述できて便利であるため、それらのカスタム実装を見つけることは珍しくありません。Springアプリでは、アプリで実行できることのほとんどはSpring Beanで行われます。ただし、Filterインスタンスはサーブレットコンテナによって制御されます。コンテナはインスタンス化、初期化、破棄します。ただし、サーブレット仕様ではSpringとの統合は一切必要ないため、Springアプリとその機能を実行するBeanに結び付ける便利な方法がないため、非常に便利な概念(フィルター)が残ります。

DelegatingFilterProxyを入力します。Filter実装を作成してSpring Beanにしますが、独自のFilterクラスをweb.xmlに追加する代わりに、DelegatingFilterProxyを使用して、SpringコンテキストでフィルターのBean名を指定します。(名前を明示的に指定しない場合は、「filter-name」が使用されます。)次に、実行時に、DelegatingFilterProxyが実際の実装(Springで作成して構成した実装)を見つける複雑さを処理し、要求をルーティングします。 。したがって、実行時には、web.xmlにフィルターをリストしたかのように見えますが、他のSpring Beanと同じようにフィルターをかけることができるという利点があります。

web.xmlからそのフィルターマッピングを削除すると、すべてが機能し続けますが、保護されているURLはありません。(これは、「springSecurityFilterChain」という名前がその機能を正確に説明していることを前提としています。)これは、このマッピングがすべての着信要求をフィルタリングし、Springコンテキストで定義されているセキュリティフィルターにそれを渡すためです。


この明るいコメントを投稿していただきありがとうございます。私は今、Spring Securityを習得しており、カスタマイズを行うために十分に理解しようとしています。サーブレットフィルターとは何か、スプリングフィルターとは何なのかわかりませんでした。AOPについて少し理解すると、サーブレットを使用する代わりにフィルターを使用する理由が明らかになります。したがって、各サーブレット/リソースで同じ前処理/後処理を何度も繰り返す必要はありません
Steve

ワオ。その説明はまさに私が必要としたものです。あなたの知識を共有していただきありがとうございます。
Charles Morin

@Ryan Stewartが2つのBeanを実装していて、applicationContextにFilterインターフェースを実装していて、順序どおりに実行したい場合、どうすれば作成できますか?
Abhishek Nayak 2014年

@skaffman 2つのBeanがapplicationContextにFilterインターフェースを実装していて、順番に実行したい場合、どうすればそれを作成できますか?
Abhishek Nayak 2014年

44

サーブレットフィルターとは

サーブレットフィルターは、一般に、Java WebAppの概念です。アプリケーションでSpringフレームワークを使用するかどうかに関係なく、任意のWebアプリケーションでサーブレットフィルターを使用できます。

これらのフィルタは、ターゲットサーブレットに到達する前にリクエストをインターセプトできます。承認などの一般的な機能をサーブレットフィルタに実装できます。実装したら、web.xml内のフィルターを構成して、特定のサーブレット、特定の要求URLパターン、またはすべてのURLパターンに適用できます。

サーブレットフィルターはどこで使用されますか?

最近のWebアプリは、そのようなフィルターを数十個持つことができます。認可、キャッシング、ORMセッション管理、依存性注入などは、サーブレットフィルターを使用して実装されることがよくあります。これらのフィルターはすべてに登録する必要がありますweb.xml

サーブレットフィルターのインスタンス化-Spring Frameworkなし

サーブレットコンテナは、で宣言されたFiltersのインスタンスを作成web.xmlし、適切なときに(つまり、サーブレットリクエストを処理するときに)それらを呼び出します。Dependency Injection(DI)ファンのほとんどが好きなら、インスタンスの作成が私のDIフレームワーク(Spring)の方が優れていると言えるでしょう。Springで作成したサーブレットフィルターを取得して、すべてのDIの良さを受け入れることができませんか?

DelegatingFilterProxy、Springがフィルターインスタンスを作成するように

ここで、DelegatingFilterProxyステップインDelegatingFilterProxyは、javax.servlet.FilterSpring Frameworkによって提供されるインターフェースの実装です。DelegatingFilterProxyweb.xmlで設定したら、実際のBeanを宣言できますフィルタリングを行うをます。このように、Springは実際のフィルタリングを行うBeanのインスタンスを作成し、DIを使用してこれらのBeanを構成できます。

で必要なDelegatingFilterProxy宣言は1つだけweb.xmlですがbean、アプリケーションコンテキストでチェーンされた複数のフィルタリングを行うことができます。


とてもよく説明されました。
user4906240 2017

15

問題は、サーブレットフィルターは、スプリングではなくサーブレットコンテナーによって管理されることです。そして、いくつかのスプリングコンポーネントをフィルターに注入する必要があるかもしれません。

したがって、次のようなものが必要な場合:

public class FooFilter {

    @Inject
    private FooService service;

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

}

次に、委任フィルタープロキシが必要です。


1

あなたは「接着剤」について正しいです。FilterChainProxyのJavaDocsに書かれているように:

FilterChainProxyは、アプリケーションのweb.xmlファイルに標準のSpring DelegatingFilterProxy宣言を追加することにより、サーブレットコンテナーのフィルターチェーンにリンクされます。

優れた説明については、Spring Security Namespaceの背後にあるブログのFIlterChainProxyセクションを参照してください。


0

私はweb.xmlの "springSecurityFilterChain"に困惑しており、この答えをspringframeworkセキュリティドキュメントで見つけました。

<http>要素は、アプリケーションのウェブ層のセキュリティ設定をカプセル化します。>これは、「springSecurityFilterChain」という名前のFilterChainProxy Beanを作成し、Webセキュリティ構成を構成するセキュリティフィルターのスタックを維持します[19]。>いくつかのコアフィルターは常に作成され、他は存在する属性の子要素に応じてスタックに追加されます。標準フィルターの位置は固定され(名前空間の紹介のフィルター順序表を参照)、ユーザーがFilterChainProxy Beanでフィルターチェーンを明示的に構成する必要があったときに、フレームワークの以前のバージョンでのエラーの一般的な原因が取り除かれます。もちろん、構成を完全に制御する必要がある場合でも、これを行うことができます。

ここにリンクがありますhttp://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html


0

それは長い間ですが、同じ質問があり、これを見つけました:https : //www.javacodegeeks.com/2013/11/spring-security-behind-the-scenes.html

問題のフィルターを削除して追加することで、春のセキュリティプロジェクトを実行しようとしました。私が見つけたのは、フィルターを追加した場合にのみ、呼び出しは、スプリングセキュリティ構成で定義されている必要なログインページにリダイレクトされます。

したがって、@ Ryanの回答に同意します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.