第1章 HTTP と互換性のあるバインディングのセキュリティー

概要

本章では、Apache CXF HTTP トランスポートによってサポートされるセキュリティー機能について説明します。これらのセキュリティー機能は、HTTP トランスポートの上に階層化できる Apache CXF バインディングで使用できます。

概要

本セクションでは、通常 HTTPS と呼ばれる組み合わせである SSL/TLS セキュリティーを使用するように HTTP トランスポートを設定する方法を説明します。Apache CXF では、XML 設定ファイルに設定を指定して、HTTPS セキュリティーを設定します。

警告

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

本章では、以下のトピックについて説明します。

X.509 証明書の生成

SSL/TLS セキュリティーを使用するための基本的な前提条件は、サーバーアプリケーションを識別するための X.509 証明書のコレクションと、任意でクライアントアプリケーションを特定することです。X.509 証明書は、以下のいずれかの方法で生成できます。

注記

HTTPS プロトコルは URL 整合性チェック を行います。これには、サーバーがデプロイされているホスト名と一致する証明書のアイデンティティーが必要です。詳しくは、「HTTPS 証明書の特別な要件」 を参照してください。

証明書の形式

Java ランタイムでは、X.509 証明書チェーンおよび信頼できる CA 証明書を Java キーストアの形式でデプロイする必要があります。詳しくは、3章HTTPS の設定 を参照してください。

HTTPS の有効化

WSDL エンドポイントで HTTPS を有効にするための前提条件として、エンドポイントアドレスを HTTPS URL として指定する必要があります。エンドポイントアドレスが設定され、両方とも HTTPS URL を使用するように変更する必要がある 2 つの場所があります。

  • WSDL コントラクトで指定した HTTPS では、例1.1「WSDL での HTTPS の指定」 のように、WSDL 契約のエンドポイントアドレスを https: 接頭辞を持つ URL に指定する必要があります。

    例1.1 WSDL での HTTPS の指定

    <wsdl:definitions name="HelloWorld"
                    targetNamespace="http://apache.org/hello_world_soap_http"
                    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ... >
      ...
      <wsdl:service name="SOAPService">
        <wsdl:port binding="tns:Greeter_SOAPBinding"
                   name="SoapPort">
          <soap:address location="https://localhost:9001/SoapContext/SoapPort"/>
        </wsdl:port>
      </wsdl:service>
    </wsdl:definitions>

    soap:address 要素の location 属性は、HTTPS URL を使用するように設定されています。SOAP 以外のバインディングの場合、http:address 要素の location 属性に表示される URL を編集します。

  • サーバーコードで指定された HTTPS — 例1.2「サーバーコードでの HTTPS の指定」 で示されるように、Endpoint.publish() を呼び出すことでサーバーコードに公開されている URL が、https: 接頭辞で定義されていることを確認する必要があります。

    例1.2 サーバーコードでの HTTPS の指定

    // Java
    package demo.hw_https.server;
    import javax.xml.ws.Endpoint;
    
    public class Server {
      protected Server() throws Exception {
        Object implementor = new GreeterImpl();
        String address = "https://localhost:9001/SoapContext/SoapPort";
        Endpoint.publish(address, implementor);
      }
      ...
      }

証明書のない HTTPS クライアント

たとえば、例1.3「証明書のない HTTPS クライアントのサンプル」 に示されるように、証明書のないセキュアな HTTPS クライアントの設定について考えてみましょう。

例1.3 証明書のない HTTPS クライアントのサンプル

<?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:sec="http://cxf.apache.org/configuration/security"
       xmlns:http="http://cxf.apache.org/transports/http/configuration"
       xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
       xsi:schemaLocation="...">

    <http:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit">
      <http:tlsClientParameters>
        <sec:trustManagers>
          <sec:keyStore type="JKS" password="password"
                        file="certs/truststore.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>

上記のクライアント設定については、以下で説明します。

TLS セキュリティー設定は特定の WSDL ポートで定義されます。この例では、設定される WSDL ポートには QName {http://apache.org/hello_world_soap_http}SoapPort が設定されています。

http:tlsClientParameters 要素には、クライアントの TLS 設定の詳細がすべて含まれます。

sec:trustManagers 要素は、信頼できる CA 証明書の一覧を指定するために使用されます (クライアントはこの一覧を使用して、サーバー側から受信した証明書を信頼するかどうかを決定します)。

sec:keyStore 要素の file 属性は、1 つ以上の信頼できる CA 証明書が含まれる Java キーストアファイル truststore.jks を指定します。password 属性は、キーストアへのアクセスに必要なパスワードを指定します (truststore.jks)。「HTTPS の信頼された CA 証明書の指定」を参照してください。

注記

file 属性の代わりに、resource 属性 (クラスパスでキーストアファイルが提供される場合) または url 属性のいずれかを使用してキーストアの場所を指定できます。特に、OSGi コンテナーにデプロイされるアプリケーションで resource 属性を使用する必要があります。信頼されていないソースからトラストストアを読み込まないように細心の注意を払う必要があります。

sec:cipherSuitesFilter 要素を使用すると、クライアントが TLS 接続に使用する暗号スイートの選択肢を絞り込むことができます。詳しくは、4章HTTPS 暗号化スイートの設定 を参照してください。

証明書を含む HTTPS クライアント

独自の証明書が設定されているセキュアな HTTPS クライアントについて考えてみましょう。例1.4「証明書を使用する HTTPS クライアントの例」 は、このようなサンプルクライアントを設定する方法を示しています。

例1.4 証明書を使用する HTTPS クライアントの例

<?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:sec="http://cxf.apache.org/configuration/security"
 xmlns:http="http://cxf.apache.org/transports/http/configuration"
 xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
 xsi:schemaLocation="...">

  <http:conduit name="{http://apache.org/hello_world_soap_http}SoapPort.http-conduit">
    <http:tlsClientParameters>
      <sec:trustManagers>
          <sec:keyStore type="JKS" password="password"
               file="certs/truststore.jks"/>
      </sec:trustManagers>
      <sec:keyManagers keyPassword="password">
           <sec:keyStore type="JKS" password="password"
                file="certs/wibble.jks"/>
      </sec:keyManagers>
      <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>

    <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl"/>
</beans>

上記のクライアント設定については、以下で説明します。

sec:keyManagers 要素は、X.509 証明書と秘密鍵をクライアントに割り当てるために使用されます。keyPasswod 属性で指定されるパスワードは、証明書の秘密鍵を復号するために使用されます。

sec:keyStore 要素は、Java キーストアに保存される X.509 証明書と秘密鍵を指定するために使用されます。この例では、キーストアが Java Keystore Format (JKS) であることを宣言します。

file 属性は、キーストアファイル wibble.jks の場所を指定します。これには、クライアントの X.509 証明書チェーンと キーエントリー の秘密鍵が含まれています。password 属性は、キーストアのコンテンツへのアクセスに必要なキーストアパスワードを指定します。

キーストアファイルにはキーエントリーが 1 つだけ含まれるため、エントリーを識別するキーエイリアスを指定する必要はありません。複数 のキーエントリーを持つキーストアファイルをデプロイする場合は、以下のように sec:certAlias 要素を http:tlsClientParameters 要素の子として追加することで、キーを指定することができます。

<http:tlsClientParameters>
    ...
    <sec:certAlias>CertAlias</sec:certAlias>
    ...
</http:tlsClientParameters>

キーストアファイルの作成方法は 「CA を使用した Java キーストアでの署名証明書の作成」 を参照してください。

注記

file 属性の代わりに、resource 属性 (クラスパスでキーストアファイルが提供される場合) または url 属性のいずれかを使用してキーストアの場所を指定できます。特に、OSGi コンテナーにデプロイされるアプリケーションで resource 属性を使用する必要があります。信頼されていないソースからトラストストアを読み込まないように細心の注意を払う必要があります。

HTTPS サーバーの設定

クライアントが X.509 証明書を提示する必要があるセキュアな HTTPS サーバーについて考えてみましょう。例1.5「HTTPS サーバーの設定例」 は、このようなサーバーを設定する方法を示しています。

例1.5 HTTPS サーバーの設定例

<?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:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xsi:schemaLocation="...">

  <httpj:engine-factory bus="cxf">
   <httpj:engine port="9001">
    <httpj:tlsServerParameters secureSocketProtocol="TLSv1">
      <sec:keyManagers keyPassword="password">
           <sec:keyStore type="JKS" password="password"
                file="certs/cherry.jks"/>
      </sec:keyManagers>
      <sec:trustManagers>
          <sec:keyStore type="JKS" password="password"
               file="certs/truststore.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="true"/>
    </httpj:tlsServerParameters>
   </httpj:engine>
  </httpj:engine-factory>

</beans>

上記のサーバー設定は、以下のとおりです。

bus 属性は、関連する CXF Bus インスタンスを参照します。デフォルトでは、ID が cxf の CXF Bus インスタンスは、Apache CXF ランタイムによって自動的に作成されます。

サーバー側では、TLS は WSDL ポートごとに設定されて いません。各 WSDL ポートを設定する代わりに、TLS セキュリティー設定が特定の TCP ポート (この例では 9001) に適用されます。そのため、この TCP ポートを共有するすべての WSDL ポートは、同じ TLS セキュリティー設定で設定されています。

http:tlsServerParameters 要素には、サーバーの TLS 設定の詳細がすべて含まれます。

重要

Poodle 脆弱性 (CVE-2014-3566) から保護するために、サーバー側で secureSocketProtocol を TLSv1 に設定する必要があります。

sec:keyManagers 要素は、X.509 証明書と秘密鍵をサーバーに割り当てるために使用されます。keyPasswod 属性で指定されるパスワードは、証明書の秘密鍵を復号するために使用されます。

sec:keyStore 要素は、Java キーストアに保存される X.509 証明書と秘密鍵を指定するために使用されます。この例では、キーストアが Java Keystore Format (JKS) であることを宣言します。

file 属性は、キーストアファイル cherry.jks の場所を指定します。これには、クライアントの X.509 証明書チェーンと キーエントリー の秘密鍵が含まれています。password 属性は、キーストアのコンテンツへのアクセスに必要なキーストアパスワードを指定します。

キーストアファイルにはキーエントリーが 1 つだけ含まれるため、エントリーを識別するキーエイリアスを指定する必要はありません。複数 のキーエントリーを持つキーストアファイルをデプロイする場合は、以下のように sec:certAlias 要素を http:tlsClientParameters 要素の子として追加することで、キーを指定することができます。

<http:tlsClientParameters>
    ...
    <sec:certAlias>CertAlias</sec:certAlias>
    ...
</http:tlsClientParameters>
注記

file 属性の代わりに、resource 属性または url 属性のいずれかを使用してキーストアの場所を指定できます。信頼されていないソースからトラストストアを読み込まないように細心の注意を払う必要があります。

このようなキーストアファイルを作成する方法は、「CA を使用した Java キーストアでの署名証明書の作成」 を参照してください。

sec:trustManagers 要素は、信頼できる CA 証明書の一覧を指定するために使用されます (サーバーはこの一覧を使用して、クライアントが提示する証明書を信頼するかどうかを判断します)。

sec:keyStore 要素の file 属性は、1 つ以上の信頼できる CA 証明書が含まれる Java キーストアファイル truststore.jks を指定します。password 属性は、キーストアへのアクセスに必要なパスワードを指定します (truststore.jks)。「HTTPS の信頼された CA 証明書の指定」を参照してください。

注記

file 属性の代わりに、resource 属性または url 属性のいずれかを使用してキーストアの場所を指定できます。

sec:cipherSuitesFilter 要素を使用すると、サーバーが TLS 接続に使用する暗号スイートの選択肢を絞り込むことができます。詳しくは、4章HTTPS 暗号化スイートの設定 を参照してください。

sec:clientAuthentication 要素は、クライアント証明書の提示に対するサーバーの処理を決定します。要素には以下の属性があります。

  • want 属性 — true (デフォルト) の場合、サーバーは TLS ハンドシェイク中に、X.509 証明書を提示するようにクライアントに要求します。false の場合は、サーバーはクライアントに X.509 証明書の提示を 要求しません
  • required 属性 — true の場合、TLS ハンドシェイク中にクライアントが X.509 証明書を提示できないと、サーバーは例外を発生させます。false (デフォルト) の場合は、クライアントが X.509 証明書を提示できなくても、サーバーは 例外を発生させません