Menu Close

第5章 Camel CXF コンポーネントのセキュア化

概要

本章では、Camel CXF プロキシーのデモンストレーションを開始点として使用して、Camel CXF エンドポイントで SSL/TLS セキュリティーを有効にする方法を説明します。Camel CXF コンポーネントを使用すると、Apache CXF エンドポイントを Apache Camel ルートに追加できます。これにより、Apache Camel で Web サービスをシミュレートでき、WS クライアントと Web サービスとの間のルートに割り込み、追加の処理 (ここで考慮される) を実行することもできます。

5.1. Camel CXF プロキシーのデモンストレーション

概要

OSGi で Camel CXF エンドポイントを保護する方法を説明するために、このチュートリアルは、Camel CXF プロキシーデモンストレーションである Apache Camel のスタンドアロンディストリビューションから入手できる例に構築されます。図5.1「Camel CXF プロキシーの概要」 はこのデモの仕組みの概要を示しています。

図5.1 Camel CXF プロキシーの概要

camel cxf 01

RealWebServiceBean によって実装されたレポートインシデント Web サービスは、インシデント (例: 交通事故) の詳細を受信し、クライアントに追跡コードを返します。ただし、WS クライアントはリクエストを実際の Web サービスに直接送信するのではなく、WS クライアントと実際の Web サービスとの間に割り込まれる Camel CXF エンドポイントに接続します。Apache Camel ルートは (enrichBean を使用して) WSDL メッセージに何らかの処理を実行した後に実際の Web サービスに転送します。

警告

SSL/TLS セキュリティーを有効にする場合、Poodle の脆弱性 (CVE-2014-3566) から保護するために、SSLv3 プロトコルを明示的に無効にする必要があります。詳細は、「Disabling SSLv3 in JBoss Fuse 6.x and JBoss A-MQ 6.x」を参照してください。

変更

OSGi のコンテキストで Camel CXF エンドポイントの SSL/TLS を有効にする方法を示すために、この章では、基本的なデモンストレーションを次のように変更する方法について説明します。

  1. WS クライアントと Camel CXF エンドポイントとの間の接続で SSL/TLS セキュリティーが有効になります。
  2. Apache Camel ルートと RealWebServiceBean Bean の両方が OSGi コンテナーにデプロイされます。

デモンストレーションコードの取得

Camel CXF プロキシーのデモンストレーションは、InstallDir/extras ディレクトリーに含まれる Apache Camel のスタンドアロンディストリビューションでのみ利用可能です。標準のアーカイブユーティリティーを使用して Camel アーカイブファイルを展開し、ファイルシステムの便利な場所にコンテンツを抽出します。

Apache Camel を CamelInstallDir にインストールしている場合、以下のディレクトリーに Camel CXF プロキシーのデモンストレーションがあります。

CamelInstallDir/examples/camel-example-cxf-proxy

サンプル証明書の取得

このデモンストレーションには X.509 証明書が必要です。実際のデプロイメントでは、プライベート認証局を使用してこれらの証明書を独自に生成する必要があります。ただし、このデモでは、Apache CXF の wsdl_first_http の例からいくつかのサンプル証明書を使用します。このデモは、InstallDir/extras ディレクトリーに含まれる Apache CXF のスタンドアロンディストリビューションから入手できます。標準のアーカイブユーティリティーを使用して CXF アーカイブファイルを展開し、ファイルシステムの便利な場所にコンテンツを抽出します。

Apache CXF を CXFInstallDir にインストールしている場合、以下のディレクトリーに wsdl_first_http デモンストレーションがあります。

CXFInstallDir/samples/wsdl_first_http

WSDL コントラクトの物理部分

WSDL コントラクトの物理部分は、wsdl:service および wsdl:port 要素を参照します。これらの要素は、特定の Web サービスエンドポイントに接続するために必要なトランスポートの詳細を指定します。このデモの目的では、これがコントラクトで最も興味深い部分で、例5.1「ReportIncidentEndpointService WSDL サービス」 に示されています。

例5.1 ReportIncidentEndpointService WSDL サービス

<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
    ...
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	targetNamespace="http://reportincident.example.camel.apache.org">
    ...
    <!-- Service definition -->
    <wsdl:service name="ReportIncidentEndpointService">
        <wsdl:port name="ReportIncidentEndpoint" binding="tns:ReportIncidentBinding">
            <soap:address location="http://localhost:9080/camel-example-cxf-proxy/webservices/incident"/>
        </wsdl:port>
    </wsdl:service>

</wsdl:definitions>
注記

WSDL コントラクトに表示されるアドレス URL ( soap:address 要素の location 属性の値) は、アプリケーションコードがアドレス URL のデフォルト値を上書きするため、ここでは重要ではありません。

WSDL アドレッシングの詳細

WS クライアントには、WSDL サービスに接続するための 3 つの情報が必要です。これらは WSDL サービス名WSDL ポート名、および Web サービスのアドレス URL です。この例では、プロキシ Web サービスおよび実際の Web サービスへの接続には、次のアドレッシングの詳細が使用されます。

WSDL サービス名

WSDL サービスの完全な QName は以下のとおりです。

{http://reportincident.example.camel.apache.org}ReportIncidentEndpointService
WSDL ポート名

WSDL ポートの完全な QName は以下のとおりです。

{http://reportincident.example.camel.apache.org}ReportIncidentEndpoint
アドレス URL

プロキシー Web サービスエンドポイント (HTTPS プロトコルを使用する) のアドレス URL は以下のとおりです。

https://localhost:9080/camel-example-cxf-proxy/webservices/incident
注記

reportIncident Bean がバンドルの Spring 設定ファイル src/main/resources/META-INF/spring/camel-config.xmlcxf:cxfEndpoint 要素を使用して作成されると、前述のアドレスが指定されます。

実際の Web サービスエンドポイント (HTTP プロトコルを使用) のアドレス URL は以下のとおりです。

http://localhost:9081/real-webservice
注記

realWebService Bean がバンドルの Spring 設定ファイル src/main/resources/META-INF/spring/camel-config.xml で作成されると、前述のアドレスが指定されます。

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

camel cxf 03

Web サービスエンドポイントと httpj:engine-factory 要素間の接続は、以下のように確立されます。

  1. Spring コンテナーは httpj:engine-factory 要素を含むファイルをロードおよび解析します。
  2. httpj:engine-factory Bean が作成されると、対応するエントリーがレジストリーに作成され、Bean への参照が格納されます。httpj:engine-factory Bean は、指定の TCP ポートをリッスンする Jetty コンテナーを初期化するために使用されます。
  3. WS エンドポイントが作成されると、レジストリーをスキャンし、エンドポイントのアドレス URL の TCP ポートと同じ TCP ポートを持つ httpj:engine-factory Bean を検索できるかどうかを確認します。
  4. 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 のプレフィックスは、後のステップで定義します。

httpj:engine-factory 要素の Spring への追加

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: namespace プレフィックスを定義します。

<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
       ">
注記

xsi:schemaLocation 属性で http://cxf.apache.org/configuration/security スキーマと http://cxf.apache.org/transports/http-jetty/configuration スキーマの場所を指定することが不可欠です。これらは OSGi コンテナーによって自動的に提供されません。

HTTPS を使用するようにプロキシーアドレス URL を変更

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 を指定します。

5.3. Apache Camel ルートのデプロイ

概要

基本的な Camel CXF プロキシーのデモンストレーションの Maven POM ファイルは、OSGi バンドルを生成するためにすでに設定されています。そのため、Maven を使用してデモンストレーションをビルドした後、Apache Camel ルートと RealWebServicesBean Bean が含まれるデモンストレーションバンドルを OSGi コンテナーにデプロイする準備が整います。

前提条件

Apache Camel ルートを OSGi コンテナーにデプロイする前に、前セクション 「Web サービスプロキシーのセキュア化」 の説明どおりに SSL/TLS セキュリティーを使用するようにプロキシー Web サービスを設定する必要があります。

Camel ルートのデプロイ手順

Web サービスプロキシーのデモンストレーションを OSGi コンテナーにデプロイするには、以下の手順を実行します。

デモンストレーションの構築

Maven を使用して、デモンストレーションを OSGi バンドルとしてビルドおよびインストールします。コマンドプロンプトを開き、現在のディレクトリーを CamelInstallDir/examples/camel-example-cxf-proxy に切り替えて、以下のコマンドを入力します。

mvn install -Dmaven.test.skip=true

OSGi コンテナーの起動

まだ起動していない場合は、新しいコマンドプロンプトに以下のコマンドを入力して、Karaf コンソール (およびコンテナーインスタンス) を起動します。

./fuse

必要な機能のインストール

Camel/CXF コンポーネントに必要なバンドルを定義する camel-cxf 機能は、デフォルトではインストールされませんcamel-cxf 機能をインストールするには、以下のコンソールコマンドを入力します。

JBossFuse:karaf@root> features:install camel-cxf

また、Camel/HTTP コンポーネントに必要なバンドルを定義する camel-http 機能も必要です。camel-http 機能をインストールするには、以下のコンソールコマンドを入力します。

JBossFuse:karaf@root> features:install camel-http

バンドルのデプロイ

以下のコンソールコマンドを入力して camel-example-cxf-proxy バンドルをデプロイします。

JBossFuse:karaf@root> install -s mvn:org.apache.camel/camel-example-cxf-proxy/2.23.2.fuse-780036-redhat-00001
注記

この場合、コンソール画面でバンドル出力を確認できるように、ホットデプロイではなく、install を使用してバンドルを直接デプロイすることが推奨されます。

mvn URL ハンドラーの使用に問題がある場合は、設定方法の詳細を「olink: esbosguide/urlHandlers-Maven」で確認してください。

コンソールの出力の確認

バンドルが正常にデプロイされると、コンソールウィンドウに以下のような出力が表示されます。

JBossFuse:karaf@root> Starting real web service...
Started real web service at: http://localhost:9081/real-webservice

5.4. Web サービスクライアントのセキュア化

概要

基本的な Camel CXF プロキシーのデモンストレーションでは、Web サービスクライアントは実際には src/test ディレクトリーに JUnit テストとして実装されます。そのため、クライアントは Maven コマンド mvn test を使用して簡単に実行できます。クライアントで SSL/TLS セキュリティーを有効にするため、テストクライアントの Java 実装が完全に置き換えられ、SSL/TLS 設定を含む Spring ファイルが src/test/resources/META-INF/spring ディレクトリーに追加されます。クライアントのセットアップに必要なステップを説明する前に、このセクションではクライアントの Java コードと Spring 設定の詳細を一部説明します。

暗黙的な設定

エンドポイントアドレスの URL スキームを https: に変更する以外に、クライアントプロキシーで SSL/TLS セキュリティーを有効にする設定のほとんどは、Spring 設定の http:conduit 要素に含まれます。ただし、この設定をクライアントプロキシーに適用する方法は、混乱を招く可能性があります。それは、http:conduit 要素によってクライアントプロキシーが明示的に参照されず、クライアントプロキシーは http:conduit 要素を明示的に参照しないためです。http:conduit 要素とクライアントプロキシー間の接続は暗黙的に確立され、http: conduit によって暗黙的に設定されたクライアントプロキシー が示すように、いずれも同じ WSDL ポートを参照します。

http: conduit によって暗黙的に設定されたクライアントプロキシー

Element

camel cxf 02

以下のように、クライアントプロキシーと http:conduit 要素間の接続が確立されます。

  1. クライアントは http:conduit 要素が含まれる Spring 設定ファイルをロードおよび解析します。
  2. http:conduit Bean が作成されると、対応するエントリーがレジストリーに作成されます。これは、指定の WSDL ポート名の下に Bean への参照を保存します (名前は QName 形式で保存されます)。
  3. JAX-WS クライアントプロキシーが作成されると、レジストリーをスキャンし、プロキシーの WSDL ポート名に関連付けられた http:conduit Bean を見つけられるかどうかを確認します。このような Bean を見つけると、設定の詳細が自動的にプロキシーに注入されます。

クライアント側で必要な証明書

クライアントは、src/main/resources/certs ディレクトリーの以下の clientKeystore.jks キーストアファイルで設定されます。このキーストアには、次の 2 つのエントリーが含まれています。

信頼できる証明書エントリー
サーバー証明書およびクライアント証明書の両方を発行および署名した CA 証明書が含まれる信頼できる証明書エントリー。
プライベートキーエントリー
クライアント独自の X.509 証明書と秘密鍵が含まれる秘密鍵エントリー。実際、TLS ハンドシェイク時にサーバーはクライアントによる証明書の送信を必要としないため、この証明書は現在のサンプルを実行するために厳密には必要はありません (例5.2「SSL/TLS が有効な httpj:engine-factory 要素」 を参照してください)。

Spring 定義のクライアントへのロード

クライアントサンプルは Spring コンテナーに直接デプロイされませんが、セキュアな HTTP コンジットを定義するためには、Spring 定義が一部必要になります。そのため、Spring コンテナーなしで Spring 定義を作成する方法を説明します。org.apache.cxf.bus.spring.SpringBusFactory クラスを使用すると、Spring 定義を Java ベースのクライアントに簡単に読み取ることができます。

以下のコードは、META-INF/spring/cxf-client.xml ファイルから Spring 定義を読み取り、これらの定義を取り入れた Apache CXF Bus オブジェクトを作成する方法を示しています。

// Java
import org.apache.cxf.bus.spring.SpringBusFactory;
...
protected void startCxfBus() throws Exception {
    bf = new SpringBusFactory();
    Bus bus = bf.createBus("META-INF/spring/cxf-client.xml");
    bf.setDefaultBus(bus);
}

クライアントプロキシーの作成

原則として、WSDL プロキシーの作成にはいくつかの方法があります。JAX-WS API を使用して WSDL ファイルの内容に基づいてプロキシーを作成したり、WS-WS API を使用して WSDL ファイルなしでプロキシーを作成できます。また、Apache CXF 固有のクラス JaxWsProxyFactoryBean を使用してプロキシーを作成できます。

この SSL/TLS クライアントの場合、以下の Java の例のように、WSDL ファイルを使用せずに JAX-WS API を使用してプロキシーを作成することが最も便利な方法です。

// Java
import javax.xml.ws.Service;
import org.apache.camel.example.reportincident.ReportIncidentEndpoint;
...
// create the webservice client and send the request
Service s = Service.create(SERVICE_NAME);
s.addPort(
    PORT_NAME,
    "http://schemas.xmlsoap.org/soap/",
    ADDRESS_URL
  );
ReportIncidentEndpoint client =
  s.getPort(PORT_NAME, ReportIncidentEndpoint.class);
注記

この例では、JaxWsProxyFactoryBean のアプローチを使用してプロキシーを作成できません。これは、このように作成されたプロキシーは Spring 設定ファイルで指定された HTTP コンジット設定を見つけることができないためです。

SERVICE_NAME および PORT_NAME 定数は、例5.1「ReportIncidentEndpointService WSDL サービス」 で定義されているように、それぞれ WSDL サービスおよび WSDL ポートの QNames です。ADDRESS_URL 文字列には、プロキシー Web サービスアドレスと同じ値があり、以下のように定義されます。

private static final String ADDRESS_URL =
  "https://localhost:9080/camel-example-cxf-proxy/webservices/incident";

特に、このアドレスは URL スキーム https で定義し、SSL/TLS 経由の HTTP を選択する必要があることに注意してください

クライアントに SSL/TLS セキュリティーを追加する手順

SSL/TLS セキュリティーを有効にして JAX-WS クライアントを定義するには、以下の手順を実行します。

Java クライアントをテストケースとして作成します。

例5.3「ReportIncidentRoutesTest Java client」 は、JUnit テストケースとして実装される Java クライアントの完全なコードを示しています。このクライアントは、examples/camel-example-cxf-proxy デモンストレーションの src/test/java/org/apache/camel/example/reportincident サブディレクトリーの既存のテストである ReportIncidentRoutesTest.java を置き換えます。

クライアントを CamelInstallDir/examples/camel-example-cxf-proxy デモンストレーションに追加するには、src/test/java/org/apache/camel/example/reportincident サブディレクトリーに移動し、既存の ReportIncidentRoutesTest.java ファイルをバックアップの場所に移動し、新しい ReportIncidentRoutesTest.java ファイルを作成し、例5.3「ReportIncidentRoutesTest Java client」 からこのファイルにコードを貼り付けます。

例5.3 ReportIncidentRoutesTest Java client

// Java
package org.apache.camel.example.reportincident;

import org.apache.camel.spring.Main;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBusFactory;
import org.apache.camel.example.reportincident.ReportIncidentEndpoint;
import org.apache.camel.example.reportincident.ReportIncidentEndpointService;

import static org.junit.Assert.assertEquals;

/**
 * Unit test of our routes
 */
public class ReportIncidentRoutesTest {

    private static final QName SERVICE_NAME
        = new QName("http://reportincident.example.camel.apache.org", "ReportIncidentEndpointService");

    private static final QName PORT_NAME =
        new QName("http://reportincident.example.camel.apache.org", "ReportIncidentEndpoint");

    private static final String WSDL_URL = "file:src/main/resources/etc/report_incident.wsdl";

    // should be the same address as we have in our route
    private static final String ADDRESS_URL = "https://localhost:9080/camel-example-cxf-proxy/webservices/incident";

    protected SpringBusFactory bf;

    protected void startCxfBus() throws Exception {
        bf = new SpringBusFactory();
        Bus bus = bf.createBus("META-INF/spring/cxf-client.xml");
        bf.setDefaultBus(bus);
    }

    @Test
    public void testRendportIncident() throws Exception {
        startCxfBus();
        runTest();
    }

    protected void runTest() throws Exception {

        // create input parameter
        InputReportIncident input = new InputReportIncident();
        input.setIncidentId("123");
        input.setIncidentDate("2008-08-18");
        input.setGivenName("Claus");
        input.setFamilyName("Ibsen");
        input.setSummary("Bla");
        input.setDetails("Bla bla");
        input.setEmail("davsclaus@apache.org");
        input.setPhone("0045 2962 7576");

        // create the webservice client and send the request
        Service s = Service.create(SERVICE_NAME);
        s.addPort(PORT_NAME, "http://schemas.xmlsoap.org/soap/", ADDRESS_URL);
        ReportIncidentEndpoint client = s.getPort(PORT_NAME, ReportIncidentEndpoint.class);

        OutputReportIncident out = client.reportIncident(input);

        // assert we got a OK back
        assertEquals("OK;456", out.getCode());
    }
}

http:conduit 要素の Spring 設定への追加

例5.4「SSL/TLS が有効になっている http:conduit 要素」 は、ReportIncidentEndpoint WSDL ポートの http:conduit 要素を定義する Spring 設定を示しています。http:conduit 要素は、指定の WSDL ポートを使用するクライアントプロキシーの SSL/TLS セキュリティーを有効にするように設定されます。

クライアントテストケースに Spring 設定を追加するには、src/test/resources/META-INF/spring サブディレクトリーを作成し、お気に入りのテキストエディターを使用してファイル cxf-client.xml を作成し、例5.4「SSL/TLS が有効になっている http:conduit 要素」 の内容をそのファイルに貼り付けます。

例5.4 SSL/TLS が有効になっている http:conduit 要素

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cxf="http://camel.apache.org/schema/cxf"
       xmlns:sec="http://cxf.apache.org/configuration/security"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
       http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
       http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
       ">

  <http:conduit name="{http://reportincident.example.camel.apache.org}ReportIncidentEndpoint.http-conduit">
    <http:tlsClientParameters disableCNCheck="true" secureSocketProtocol="TLSv1">
      <sec:keyManagers keyPassword="ckpass">
          <sec:keyStore password="cspass" type="JKS"
          resource="certs/clientKeystore.jks" />
      </sec:keyManagers>
      <sec:trustManagers>
          <sec:keyStore password="cspass" type="JKS"
          resource="certs/clientKeystore.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>
    </http:tlsClientParameters>
   </http:conduit>

</beans>

上記の設定に関して、以下の点に注意してください。

  • http:conduit 要素を定義するために http: および sec: namespace プレフィックスが必要です。xsi:schemaLocation 要素では、対応する http://cxf.apache.org/configuration/security および http://cxf.apache.org/transports/http/configuration namespace の場所を指定することが不可欠です。
  • http:tlsClientParameters 要素の disableCNCheck 属性は true に設定されます。つまり、クライアントが、サーバーの X.509 証明書の Common Name がサーバーのホスト名と一致するかどうかをチェックしません。詳細は、付録A 証明書の管理 を参照してください。

    重要

    実稼働デプロイメントで CN チェックを無効にすることは推奨されません

  • sec:keystore 要素では、クラスパス上の証明書を見つける resource 属性を使用して証明書の場所が指定されます。Maven がテストを実行すると、証明書が src/main/resources/certs ディレクトリーから読み取りできるように、クラスパスで src/main/resources の内容を自動的に利用できるようにします。

    注記

    また、ファイルシステム内を検索する file 属性を使用して、証明書の場所を指定するオプションもあります。ただし、resource 属性は、バンドルにパッケージ化されたアプリケーションでの使用に適しています。

  • sec:cipherSuitesFilter 要素は、.*WITH_NULL.\* および .*DH_anon.\* に一致する暗号スイートを除外するように設定されています。これらの暗号スイートは事実上不完全であり、通常の使用を目的としたものではありません

    重要

    .*WITH_NULL.\* および .*DH_anon.\* に一致する暗号を常に除外することが推奨されます。

  • secureSocketProtocol 属性は、サーバーのプロトコルと一致するように TLSv1 に設定し、SSLv3 プロトコルが使用されないようにする必要があります (POODLE セキュリティー脆弱性 (CVE-2014-3566))。

クライアントの実行

クライアントはテストケースとして定義されるため、標準の Maven テストゴールを使用してクライアントを実行できます。クライアントを実行するには、新しいコマンドウィンドウを開き、 CamelInstallDir/examples/camel-example-cxf-proxy ディレクトリーに移動し、以下の Maven コマンドを入力します。

mvn test

テストが正常に実行されると、OSGi コンソールウィンドウに次の出力が表示されます。

Incident was 123, changed to 456

Invoked real web service: id=456 by Claus Ibsen