SpringでのDelegatingFilterProxyの概要と必要性
1. 概要
DelegatingFilterProxy は、SpringアプリケーションコンテキストにアクセスできるFilterクラスに制御を渡すことを可能にするサーブレットフィルタです。 Spring Securityはこの手法に大きく依存しています。
このチュートリアルでは、それについて詳しく説明します。
2. DelegatingFilterProxy
DelegatingFilterProxyのJavadocには、
Filterインターフェースを実装するSpring管理のBeanに委任する、標準のサーブレットフィルターのプロキシ。
サーブレットフィルタを使用する場合は、明らかにJava設定でfilter-classまたはweb.xmlとして宣言する必要があります。そうしないと、サーブレットコンテナはそれらを無視します。 SpringのDelegatingFilterProxyは、web.xmlとアプリケーションコンテキスト間のリンクを提供します。
2.1. の内部作業 DelegatingFilterProxy
DelegatingFilterProxyがどのように制御をSpringBeanに転送するかを見てみましょう。
初期化中に、DelegatingFilterProxyはfilter-nameをフェッチし、Spring ApplicationContextからその名前のBeanを取得します。 このBeanはタイプjavax.Servlet.Filter, i.eである必要があります。 「通常の」サーブレットフィルター。 着信要求は、このフィルターBeanに渡されます。
つまり、DelegatingFilterProxy’sdoFilter()メソッドは、すべての呼び出しをSpring Beanに委任し、フィルターBean内ですべてのSpring機能を使用できるようにします。
Javaベースの構成を使用している場合、ApplicationInitializerでのフィルター登録は次のように定義されます。
@Override
protected javax.servlet.Filter[] getServletFilters() {
DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
delegateFilterProxy.setTargetBeanName("applicationFilter");
return new Filter[]{delegateFilterProxy};
}
XMLを使用する場合、web.xmlファイルでは次のようになります。
applicationFilter
org.springframework.web.filter.DelegatingFilterProxy
これは、applicationFilterという名前のSpringBeanとして定義されたフィルターを通過するように任意のリクエストを行うことができることを意味します。
2.2. DelegatingFilterProxyの必要性
DelegatingFilterProxyは、SpringのWebモジュールのクラスです。 HTTP呼び出しが実際の宛先に到達する前にフィルターを通過させる機能を提供します。 DelegatingFilterProxy,を使用すると、javax.Servlet.Filter interfaceを実装するクラスをフィルターチェーンに接続できます。
例として、Spring SecurityはDelegatingFilterProxyを使用して、Springの依存性注入機能とセキュリティフィルターのライフサイクルインターフェイスを利用できるようにします。
DelegatingFilterProxyは、Springのアプリケーションコンテキストまたはweb.xml.で構成を提供することにより、リクエストURIパスに従って特定のフィルターまたは複数のフィルターを呼び出すことも活用します。
3. カスタムフィルターの作成
上記のように、DelegatingFilterProxyは、Filterインターフェースを実装する特定のSpring管理のBeanに委任するサーブレットフィルタ自体です。
次のいくつかのセクションでは、カスタムフィルタを作成し、JavaおよびXMLベースの構成を使用して構成します。
3.1. フィルタークラス
リクエストが先に進む前に、リクエスト情報をログに記録する簡単なフィルタを作成します。
まず、カスタムフィルタークラスを作成しましょう。
@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はjavax.Servlet.Filterを実装します。 このクラスには、アプリケーションコンテキストでSpring Beanとして登録するための@Componentアノテーションがあります。 このようにして、DelegatingFilterProxyクラスは、フィルターチェーンの初期化中にフィルタークラスを見つけることができます。
Note that the name of the Spring bean must be the same as the value in the filter-name provided during the registration of the custom filter in ApplicationInitializer class or in web.xml later は、the DelegatingFilterProxyクラスが、アプリケーションコンテキストでまったく同じ名前のフィルターBeanを検索するためです。
この名前のBeanが見つからない場合は、アプリケーションの起動時に例外が発生します。
3.2. Java構成によるフィルターの構成
Java構成を使用してカスタムフィルターを登録するには、AbstractAnnotationConfigDispatcherServletInitializerのgetServletFilters()メソッドをオーバーライドする必要があります。
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. web.xmlを介したフィルターの構成
web.xmlのフィルター構成がどのように見えるかを見てみましょう。
loggingFilter
org.springframework.web.filter.DelegatingFilterProxy
loggingFilter
/*
filter-class引数はタイプDelegatingFilterProxyであり、作成したフィルタークラスではありません。 このコードを実行して任意のURLにアクセスすると、CustomFilterのdoFilter()メソッドが実行され、リクエスト情報の詳細がログファイルに表示されます。
4. 結論
この記事では、DelegatingFilterProxyのしくみとその使用方法について説明しました。
Spring Securityは、DelegatingFilterProxyを広範囲に使用して、不正アクセスからWebAPI呼び出しとリソースを保護します。
ソースコードはover on GitHubで入手できます。