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にFilterのメソッドを委任することです。これにより、BeanはSpring Webアプリケーションのコンテキストライフサイクルサポートと構成の柔軟性の恩恵を受けることができます。 Beanはjavax.servlet.Filter
を実装する必要があり、filter-name要素の名前と同じ名前でなければなりません。詳細については、 DelegatingFilterProxyのJavadoc を参照してください
それで、web.xml
からこれを取り出すと、どうなりますか?私のサーブレットは、Springコンテナと通信できませんか?**
ここには何らかの魔法がありますが、最終的にはすべてが決定論的なプログラムです。
DelegatingFilterProxyは、上記で説明したフィルターであり、その目標は「委任Filterインターフェースを実装するSpring管理のBeanへ、つまり、SpringアプリケーションコンテキストでBean(「ターゲットBean」または「デリゲート」)を見つけ、呼び出します。どうして可能ですか?このBeanはjavax.servlet.Filterを実装するため、そのdoFilterメソッドが呼び出されます。
どのBeanが呼び出されますか? DelegatingFilterProxy "" targetBeanName "[...]をサポートし、SpringアプリケーションコンテキストでターゲットBeanの名前を指定します。"
Web.xmlで見たように、Beanの名前は「springSecurityFilterChain」です。
そのため、Webアプリケーションのコンテキストでは、フィルターはアプリケーションコンテキストで「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を超えるフィルターがあります)
サーブレット Filter とは何か、どのように機能するか知っていますか?これはサーブレット仕様の非常に有用な部分であり、HTTPリクエストのサービスにAOPのような概念を適用できます。多くのフレームワークは、さまざまなことにFilter実装を使用します。また、非常に簡単に作成できて便利なため、カスタム実装を見つけることも珍しくありません。 Springアプリでは、アプリでできることのほとんどはSpring Beanにあります。ただし、Filterインスタンスはサーブレットコンテナによって制御されます。コンテナは、インスタンス化、初期化、および破棄します。ただし、サーブレット仕様では、Springの統合は一切必要ないため、Springアプリと作業を行うBeanに便利な方法で結び付けることのできない、本当に便利な概念(フィルター)が残っています。
DelegatingFilterProxyを入力します。 Filter実装を作成してSpring Beanにしますが、web.xmlに独自のFilterクラスを追加する代わりに、DelegatingFilterProxyを使用し、SpringコンテキストでフィルターのBean名を付けます。 (明示的に名前を指定しない場合、「filter-name」を使用します。)その後、実行時に、DelegatingFilterProxyは実際の実装(Springで作成および設定した実装)を見つけて要求をルーティングする複雑さを処理します。 。そのため、実行時には、web.xmlにフィルターをリストしたかのように見えますが、他のSpring Beanのようにそれを配線できるという利点があります。
そのフィルターマッピングをweb.xmlから取り出した場合、すべては引き続き機能しますが、URLは保護されません。 (これは、「springSecurityFilterChain」という名前がその動作を正確に説明していると仮定しています。)これは、このマッピングがすべての着信リクエストをフィルタリングし、スプリングコンテキストで定義されたセキュリティフィルターに渡すためです。
サーブレットフィルター は、一般にJava WebAppの概念です。アプリケーションでSpringフレームワークを使用するかどうかに関係なく、Webアプリケーションでサーブレットフィルターを使用できます。
これらのフィルターは、ターゲットサーブレットに到達する前にリクエストをインターセプトできます。サーブレットフィルターには、承認などの一般的な機能を実装できます。実装したら、特定のサーブレット、特定のリクエストURLパターン、またはすべてのURLパターンに適用されるようにweb.xmlのフィルターを設定できます。
最新のWebアプリには、このようなフィルターが多数あります。認可、キャッシング、ORMセッション管理、依存性注入などは、多くの場合、サーブレットフィルターを使用して実装されます。これらのフィルターはすべてweb.xml
に登録する必要があります。
サーブレットコンテナは、web.xml
で宣言されたFiltersのインスタンスを作成し、適切なタイミングで(つまり、サーブレットリクエストを処理するときに)それらを呼び出します。今、ほとんどのDependency Injection(DI)ファンのようであれば、インスタンスの作成が私のDIフレームワーク(Spring)のほうが優れていると言うでしょう。 Springで作成されたサーブレットフィルターを取得して、すべてのDIの利点を受け入れることはできませんか?
DelegatingFilterProxy
。これにより、Springはフィルターインスタンスを作成します。ここで、DelegatingFilterProxy
がステップインします。DelegatingFilterProxy
は、Spring Frameworkが提供するjavax.servlet.Filter
インターフェースの実装です。 web.xmlでDelegatingFilterProxy
を設定したら、スプリング設定でフィルタリングを行う実際のbeansを宣言できます。このようにして、Springは実際のフィルタリングを行うBeanのインスタンスを作成し、DIを使用してこれらのBeanを構成できます。
web.xml
で必要なDelegatingFilterProxy
宣言は1つだけですが、アプリケーションコンテキストで複数のフィルタリングbean
sをチェーン化することができます。
つまり、サーブレットフィルターは、スプリングではなく、サーブレットコンテナーによって管理されます。そして、いくつかのスプリングコンポーネントをフィルターに注入する必要があるかもしれません。
したがって、次のようなものが必要な場合:
public class FooFilter {
@Inject
private FooService service;
public void doFilter(....) { .. }
}
次に、委任フィルタープロキシが必要です。
あなたは「接着剤」については正しいです。 FilterChainProxy のJavaDocsに書かれているとおり:
FilterChainProxyは、アプリケーションのweb.xmlファイルに標準のSpring DelegatingFilterProxy宣言を追加することにより、サーブレットコンテナーフィルターチェーンにリンクされます。
優れた説明については、ブログのFIlterChainProxyセクションをご覧ください Behind the Spring Security Namespace .
それは長い時間でしたが、私は同じ質問を持っていて、これを見つけました: https://www.javacodegeeks.com/2013/11/spring-security-behind-the-scenes.html
問題のフィルターを削除して追加することで、春のセキュリティプロジェクトを実行しようとしました。私が見つけたのは、フィルターを追加した場合にのみ、スプリングセキュリティ構成で定義されている必要なログインページに呼び出しがリダイレクトされることです。
したがって、@ Ryanの答えに同意します。
Web.xmlの "springSecurityFilterChain"に困惑し、springframeworkセキュリティドキュメントでこの答えを見つけました。
<http>
要素は、アプリケーションのWebレイヤーのセキュリティ構成をカプセル化します。 > Webセキュリティ構成を構成するセキュリティフィルタのスタックを保持する「springSecurityFilterChain」という名前のFilterChainProxy Beanを作成します[19]。いくつかのコアフィルターは常に作成され、その他は存在する属性の子要素に応じてスタックに追加されます。ユーザーがFilterChainProxy Beanでフィルターチェーンを明示的に構成する必要があった場合、標準フィルターの位置は固定され(名前空間の概要のフィルター順序表を参照)、以前のバージョンのフレームワークでエラーの一般的な原因が除去されました。もちろん、設定を完全に制御する必要がある場合は、これを行うことができます。
こちらがリンクです http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html