5.2. Web サービスプロキシーのセキュリティー保護
概要
このセクションでは、実際の Web サービスのプロキシーとして機能する Camel CXF エンドポイントで SSL/TLS セキュリティーを有効にする方法について説明します。X.509 証明書をすでに利用できる場合、必要なのは設定データのブロックを Spring 設定ファイル (設定データは httpj:engine-factory 要素に含まれる) に追加することだけです。ただし、Camel CXF エンドポイントが SSL/TLS 設定の詳細にどのように関連付けられるかを理解する必要があるという点のみ、少し注意が必要です。
暗黙的な設定
WS エンドポイントは、Spring でエンドポイントを作成し、その Jetty コンテナーで SSL/TLS プロパティーを設定することで設定できます。しかし、設定が若干複雑になることもあります。Jetty コンテナー (Spring の httpj:engine-factory 要素によって設定される) は、含まれる WS エンドポイントを明示的に参照せず、WS エンドポイントは Jetty コンテナーを明示的に参照しないからです。Jetty コンテナーとそれに含まれるエンドポイント間の接続は、httpj:engine-factory によって暗黙的に設定された WS エンドポイント で示されるとおり、両方が同じ TCP ポートを使用するように設定されているという点で暗黙的に確立されます。
httpj:engine-factory によって暗黙的に設定された WS エンドポイント
Element

Web サービスエンドポイントと httpj:engine-factory 要素間の接続は以下のように確立されます。
-
Spring コンテナーは、
httpj:engine-factory要素を含むファイルを読み込み、解析します。 -
httpj:engine-factoryBean が作成されると、対応するエントリーがレジストリーに作成され、Bean への参照が格納されます。httpj:engine-factoryBean は、指定の TCP ポートをリッスンする Jetty コンテナーを初期化するために使用されます。 -
WS エンドポイントが作成されると、レジストリーをスキャンし、エンドポイントのアドレス URL の TCP ポートと同じ TCP ポートを持つ
httpj:engine-factoryBean を検索できるかどうかを確認します。 - Bean の 1 つがエンドポイントの TCP ポートと一致する場合、WS エンドポイントはそれ自体を対応する Jetty コンテナーにインストールします。Jetty コンテナーで SSL/TLS が有効になっている場合、WS エンドポイントはそれらのセキュリティー設定を共有します。
Jetty コンテナーに SSL/TLS セキュリティーを追加する手順
Jetty コンテナーに SSL/TLS セキュリティーを追加して、WS プロキシーエンドポイントをセキュリティー保護するには、次の手順を実行します。
バンドルリソースへの証明書の追加
このデモンストレーションで使用される証明書は、Apache CXF 3.3.6.fuse-780029-redhat-00001 製品のサンプルから取得されます。スタンドアロンバージョンの Apache CXF (InstallDir/extras/ ディレクトリーで利用可能) をインストールする場合は、CXFInstallDir/samples/wsdl_first_https/src/main/config ディレクトリーにサンプル証明書があります。
clientKeystore.jks および serviceKeystore.jks キーストアを CXFInstallDir/samples/wsdl_first_https/src/main/config ディレクトリーから CamelInstallDir/examples/camel-example-cxf-proxy/src/main/resources/certs ディレクトリーにコピーします (最初に certs サブディレクトリーを作成する必要があります)。
POM を変更してリソースフィルターリングを無効化
証明書をリソースとしてバンドルに直接含めることは、証明書をデプロイするための最も便利な方法です。ただし、証明書を Maven プロジェクトのリソースとしてデプロイする場合は、バイナリーファイルを破損する Maven リソースフィルターリングを無効にすることを忘れないでください。
Maven で .jks ファイルのフィルターを無効にするには、プロジェクト POM ファイル、CamelInstallDir/examples/camel-example-cxf-proxy/pom.xml を開き、テキストエディターで以下の resources 要素を build 要素の子として追加します。
<?xml version="1.0" encoding="UTF-8"?>
...
<project ...>
...
<build>
<plugins>
...
</plugins>
<resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <excludes> <exclude>/.jks</exclude> </excludes> </resource> <resource> <directory>src/main/resources</directory> <filtering>false</filtering> <includes> <include>/.jks</include> </includes> </resource> </resources>
</build>
</project>CXF バスのインスタンス化
Spring XML で明示的に CXF バスをインスタンス化する必要があります (これは、次の手順の httpj:engine-factory 要素によってインスタンス化される Jetty コンテナーが利用できるようにするためです)。src/main/resources/META-INF/spring ディレクトリーの camel-config.xml ファイルを編集し、cxfcore:bus 要素を beans 要素の子として追加します。
<beans ... >
...
<cxfcore:bus/>
...
</beans>
cxfcore: namespace の接頭辞は、後のステップで定義します。
Spring への httpj:engine-factory 要素の追加
configuration
TCP ポート 9080 でリッスンする Jetty コンテナーを設定するには、src/main/resources/META-INF/spring ディレクトリーの camel-config.xml ファイルを編集し、例5.2「SSL/TLS が有効になっている httpj:engine-factory 要素」 に示されているように httpj:engine-factory 要素を追加します。
この例では、sec:clientAuthentication 要素の required 属性は false に設定されています。つまり、SSL/TLS ハンドシェイク中に、サーバーに X.509 証明書を提示する必要はありません (ただし、証明書がある場合は提示できます)。
例5.2 SSL/TLS が有効になっている httpj:engine-factory 要素
<beans ... >
...
<httpj:engine-factory bus="cxf">
<httpj:engine port="${proxy.port}">
<httpj:tlsServerParameters secureSocketProtocol="TLSv1">
<sec:keyManagers keyPassword="skpass">
<sec:keyStore resource="certs/serviceKeystore.jks" password="sspass" type="JKS"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore resource="certs/serviceKeystore.jks" password="sspass" type="JKS"/>
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_WITH_3DES_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:exclude>.*_WITH_NULL_.*</sec:exclude>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
<sec:clientAuthentication want="true" required="false"/>
</httpj:tlsServerParameters>
</httpj:engine>
</httpj:engine-factory>
</beans>
Poodle 脆弱性 (CVE-2014-3566) から保護するために、サーバー側で secureSocketProtocol を TLSv1 に設定する必要があります。
接頭辞 cxfcore:、sec:、httpj: の定義
camel-config.xml ファイルの beans 要素に次の強調表示された行を追加して、cxfcore:bus 要素と httpj:engine-factory 要素の定義に表示される cxfcore:、sec:、および httpj: 名前空間接頭辞を定義します。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cxfcore="http://cxf.apache.org/core"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd
">
http://cxf.apache.org/configuration/security スキーマと http://cxf.apache.org/transports/http-jetty/configuration スキーマの場所を xsi:schemaLocation 属性に指定することが 必須 です。これらは、OSGi コンテナーで自動的に提供されません。
プロキシーアドレス URL を変更して HTTPS の使用を有効化
Apache Camel ルート先頭のプロキシーエンドポイントは、camel-config.xml ファイルの cxf:cxfEndpoint 要素によって設定されます。デフォルトでは、このプロキシーエンドポイントは HTTP プロトコルを使用するように設定されています。ただし、代わりにセキュアな HTTPS プロトコルを使用するには、アドレス URL を変更する必要があります。camel-config.xml ファイルで、以下のフラグメントが示すように、cxf:cxfEndpoint 要素の address 属性を編集し、http: 接頭辞を https: 接頭辞に置き換えます。
<beans ...>
...
<cxf:cxfEndpoint id="reportIncident"
address="https://localhost:${proxy.port}/camel-example-cxf-proxy/webservices/incident"
endpointName="s:ReportIncidentEndpoint"
serviceName="s:ReportIncidentEndpointService"
wsdlURL="etc/report_incident.wsdl"
xmlns:s="http://reportincident.example.camel.apache.org"/>
...
</beans>
また、アドレス URL は TCP ポート ${proxy.port} を使用するように設定されています (デフォルト値は 9080)。この TCP ポート値は Jetty コンテナーに設定された値と同じであるため (http:engine-factory 要素によって設定)、このエンドポイントが Jetty コンテナーにデプロイされるようにします。cxf:cxfEndpoint の属性は、「WSDL アドレス指定の詳細」 で説明されているように WSDL アドレスの詳細を指定します。
serviceName- WSDL サービス名を指定します。
endpointName- WSDL ポート名を指定します。
address- プロキシー Web サービスのアドレス URL を指定します。