SpringでのDelegatingFilterProxyの概要と必要性
1. 概要
DelegatingFilterProxy は、SpringアプリケーションコンテキストにアクセスできるFilterクラスに制御を渡すことができるサーブレットフィルターです。 Spring Securityは、この手法に大きく依存しています。
このチュートリアルでは、それについて詳しく説明します。
2. DelegatingFilterProxy
DelegatingFilterProxy のJavadocには、
標準のサーブレットフィルタのプロキシ。フィルタインターフェイスを実装するSpring管理のBeanに委任します。
サーブレットフィルタを使用する場合は、Java-configまたはweb.xmlでfilter-classとして宣言する必要があります。そうしないと、サーブレットコンテナはそれらを無視します。 SpringのDelegatingFilterProxyは、web.xmlとアプリケーションコンテキストの間のリンクを提供します。
2.1. DelegatingFilterProxyの内部動作
DelegatingFilterProxyが制御をSpringbeanに転送する方法を見てみましょう。
初期化中に、DelegatingFilterProxyはfilter-nameをフェッチし、SpringApplicationContextからその名前のBeanを取得します。 このBeanは、タイプ javax.Servlet.Filter、ieである必要があります。 「通常の」サーブレットフィルタ。 着信リクエストは、このフィルターBeanに渡されます。
つまり、DelegatingFilterProxyの doFilter()メソッドは、すべての呼び出しを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ファイルで次のようになります。
<filter>
<filter-name>applicationFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
これは、applicationFilterという名前のSpringBeanとして定義されたフィルターを通過するように任意の要求を行うことができることを意味します。
2.2. DelegatingFilterProxyの必要性
DelegatingFilterProxy は、SpringのWebモジュールのクラスです。 実際の宛先に到達する前に、HTTP呼び出しがフィルターを通過するようにするための機能を提供します。 DelegatingFilterProxyを使用すると、 javax.Servlet.Filterインターフェースを実装するクラスをフィルターチェーンに接続できます。
例として、SpringSecurityは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を実装します。 このクラスには、アプリケーションコンテキストでSpringBeanとして登録するための@Componentアノテーションがあります。 このようにして、 DelegatingFilterProxy クラスは、フィルターチェーンの初期化中にフィルタークラスを見つけることができます。
この名前の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のフィルター構成がどのように見えるかを見てみましょう。
<filter>
<filter-name>loggingFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>loggingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
filter-class 引数は、タイプ DelegatingFilterProxy であり、作成したフィルタークラスではありません。 このコードを実行して任意のURLをヒットすると、 CustomFilter のdoFilter()メソッドが実行され、リクエスト情報の詳細がログファイルに表示されます。
4. 結論
この記事では、DelegatingFilterProxyの動作とその使用方法について説明しました。
Spring Securityは、 DelegatingFilterProxy を多用して、不正アクセスからWebAPI呼び出しとリソースを保護します。
ソースコードは、GitHubでから入手できます。