Web サービス CXF ユーザーガイド

JBoss Enterprise Application Platform 5

JBoss Enterprise Application Platform 5 向け

エディッション 5.1.2

Alessio Soldano

編集者

Rebecca Newton

Red Hat エンジニアリングコンテンツサービス

編集者

Elspeth Thorne

Red Hat エンジニアリングコンテンツサービス

概要

これは、JBoss Enterprise Application Platform 5 とパッチリリースで JBoss Web サービス CXF をインストールおよび実行するためのガイドであり、インストール、設定、およびチュートリアルを含みます。

第1章 はじめに

JBoss Web Services CXF (JBossWS-CXF) は Apache CXF に内部的に基づく JBoss Web Services スタック実装です。Apache CXF はオープンソースサービスフレームワークです。CXF では、JAX-WS などの、フロントエンドプログラミング Application Programming Interface (API) を使用してサービスを構築および開発できます。
CXF には、幅広い機能セットが含まれますが、主に以下の領域に重点を置いています。
Web サービス標準サポート
CXF は以下のものを含むさまざまな Web サービス標準をサポートします。
  • SOAP
  • WSI 基本プロファイル。
  • WSDL
  • WS-Addressing
  • WS-Policy
  • WS-ReliableMessaging
  • WS-Security
  • WS-SecurityPolicy
  • WS-SecureConversation
フロントエンド
CXF は、さまざまなフロントエンドプログラミングモデルをサポートします。CXF は JAX-WS API (TCK 準拠) を実装します。これには、アノテーションなしでクライアントとエンドポイントを作成できる単純なフロントエンドも含まれます。CXF は、Java 以来、WSDL によるコントラクトファースト開発とコードファースト開発をサポートします。
使用しやすさ
CXF は、直感的に使用しやすいように設計されています。
  • コードファーストサービスを迅速に構築するために、単純な API が存在します。
  • ツールの統合を簡単にする Maven プラグイン。
  • JAX-WS API サポート。
  • 設定を簡単にする Spring 2.x XML サポート。

第2章 インストール

警告

JBoss Web Services CXF のインストールは戻すことができません。JBoss Web Services CXF をインストールする前に JBoss Enterprise Application Platform インストールの完全なバックアップを作成する必要があります。
JBoss Web Services CXF をインストールするには以下の手順に従ってください。

手順2.1 CXF のインストール

  1. インストーラをダウンロードします。

    jboss-ep-ws-cxf-5.1.0-installer.zip をダウンロードし、Platform インストールのルートの直下にあるホーム jboss-as ディレクトリで解凍します。
  2. WS ネイティブを WS CXF と置き換えます。

    作成されたディレクトリ jbossws-cxf-installerant を実行します。

注記

この手順では、JBoss Web Services Native を含む各設定で JBoss Web Services Native を JBoss Web Services CXF と置き換えます。
このプロセスの完了後に、http://localhost:8080/jbossws にある JBossWS にアクセスできる必要があります。

第3章 サーバーサイド統合カスタマイズ

JBossWS-CXF を使用すると、JBossWS-Native の場合と同様にアーカイブを提供することにより、Web サービスエンドポイントをデプロイできます。ただし、CXF 設定ファイルをエンドポイントデプロイメントアーカイブに組み込むことによって JBossWS および CXF 統合をカスタマイズできます。要件は以下のとおりです。
  • ファイル名は jbossws-cxf.xml である必要があります。
  • POJO デプロイメントの場合は、WEB-INF ディレクトリに含まれます。
  • EJB3 デプロイメントの場合は、META-INF ディレクトリに含まれます。
ユーザーが独自の CXF 設定ファイルを提供しない場合は、実行時にデフォルトの設定ファイルが自動的に生成されます。POJO デプロイメントの場合、生成された jbossws-cxf.xml の内容は以下のようになります。
 
<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://cxf.apache.org/jaxws
  http://cxf.apache.org/schemas/jaxws.xsd'>

  <!-- one or more jaxws:endpoint POJO declarations -->
  <jaxws:endpoint
    id='POJOEndpoint'
    address='http://localhost:8080/pojo_endpoint_archive_name'  
    implementor='my.package.POJOEndpointImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerJSE'/>
    </jaxws:invoker>
  </jaxws:endpoint>
</beans>
EJB3 デプロイメントの場合、生成された jbossws-cxf.xml の内容は以下のようになります。
 
<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://cxf.apache.org/jaxws
  http://cxf.apache.org/schemas/jaxws.xsd'>

  <!-- one or more jaxws:endpoint EJB3 declarations -->
  <jaxws:endpoint
    id='EJB3Endpoint'
    address='http://localhost:8080/ejb3_endpoint_archive_name'  
    implementor='my.package.EJB3EndpointImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerEJB3'/>
    </jaxws:invoker>
  </jaxws:endpoint>
</beans>
ユーザーが標準的な JAX-WS 仕様の一部でない機能を使用する場合は、カスタム CXF 設定をエンドポイントデプロイメントに提供することが役に立ちます (CXF はこれらの機能を実装します)。詳細については、8章WS-Reliable Messaging チュートリアル を参照してください。カスタム CXF エンドポイント設定を提供してエンドポイントの WS-RM 機能を有効にします。

注記

ユーザーが独自の CXF 設定をエンドポイントアーカイブに組み込む場合は、各 JAX-WS エンドポイントの org.jboss.wsf.stack.cxf.InvokerJSE または org.jboss.wsf.stack.cxf.InvokerEJB3 JAX-WS 起動プログラム Bean を参照する必要があります。

第4章 WS Addressing

CXF は、WS-Addressing の 2004 年 8 月バージョンと 1.0 バージョンのサポートを提供します。ユーザーは標準的な JAX-WS 方式を使用するか、またはサービスで Apache CXF WS Addressing Feature を使用することによって WS-Addressing を有効にできます。

4.1. JAX-WS を使用して WS-Addressing を有効化

1 つの JAX-WS 2.1 仕様ごとに、@javax.xml.soap.Addressing アノテーションを追加して Web サービスエンドポイントで WS-Addressing を有効にできます。
 
package org.jboss.test.ws.jaxws.samples.wsa; 

import javax.jws.WebService;
import javax.xml.ws.soap.Addressing;
@WebService
@Addressing(enabled=true, required=true)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
クライアントサイドで、サービスからプロキシインスタンスを取得するときに org.apache.cxf.ws.addressing.WSAddressingFeature を提供することにより、WS-Addressing を明示的に有効にできます。
  ServiceIface proxy = (ServiceIface)service.getPort(ServiceIface.class, new AddressingFeature());
proxy.sayHello());

4.1.1. CXF プロプラエタリ WSAddressingFeature の使用

WS-Addressing を有効にするために、サービスで WSAddressingFeature を有効にします。XML を使用してこれを設定する場合は、以下の構文を使用します。
    
<jaxws:endpoint id="{your.service.namespace}YourPortName">
   <jaxws:features>
     <wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/>
   </jaxws:features>
</jaxws:endpoint>
また、<jaxws:client> でまったく同じ構文を使用することもできます。
 
<jaxws:client id="{your.service.namespace}YourPortName">
   <jaxws:features>
     <wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/>
   </jaxws:features>
</jaxws:client>

第5章 Addressing のチュートリアル

このチュートリアルでは、WS-Addressing を有効にしてクライアントおよびエンドポイントの通信を作成する方法を示します。WS-Addressing ベースのサービスとクライアントを作成するのは非常に簡単です。最初の手順は通常の JAX-WS サービスおよびクライアントの設定を作成することであり、最後の手順は両側でアドレッシングを設定することです。
サービス

以下のエンドポイント実装から始めます。

package org.jboss.test.ws.jaxws.samples.wsa;
        
import javax.jws.WebService;
  @WebService
(
   portName = "AddressingServicePort",
   serviceName = "AddressingService",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsa.ServiceIface"
)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
上記のエンドポイントは以下のエンドポイントインターフェースを実装します。
package org.jboss.test.ws.jaxws.samples.wsa;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
@WebService
(
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing"
)
public interface ServiceIface
{
   @WebMethod
   String sayHello();
}
コンパイルされたエンドポイントとインターフェースクラスがディレクトリ /home/username/wsa/cxf/classes にあるとします。次の手順はエンドポイントアーカイブの一部である JAX-WS アーティファクトと WSDL を生成することです。
WSDL および JAX-WS エンドポイントアーティファクトの生成

wsprovide コマンドラインツールを使用して WSDL および JAX-WS アーティファクトを生成します。コマンドは以下のとおりです。

 
cd JBOSS_HOME/bin
./wsprovide.sh --keep --wsdl \
   --classpath=/home/username/wsa/cxf/classes \
   --output=/home/username/wsa/cxf/wsprovide/generated/classes \
   --resource=/home/username/wsa/cxf/wsprovide/generated/wsdl \
   --source=/home/username/wsa/cxf/wsprovide/generated/src \
   org.jboss.test.ws.jaxws.samples.wsa.ServiceImpl
上記のコマンドは以下のアーティファクトを生成します。
コンパイルされたクラス
SayHello.class
SayHelloResponse.class
Java ソース
SayHello.java
SayHelloResponse.java
Contract アーティファクト
AddressingService.wsdl
以前に説明されたすべての生成済みアーティファクトはエンドポイントアーカイブの一部ですが、エンドポイントアーカイブを作成する前に、エンドポイントから生成済み WSDL を参照する必要があります。wsdlLocation アノテーション属性を使用します。これは、war ファイルにパッケージ化される前の更新済みエンドポイント実装です。
package org.jboss.test.ws.jaxws.samples.wsa;
 
import javax.jws.WebService;
 
@WebService
(
   portName = "AddressingServicePort",
   serviceName = "AddressingService",
   wsdlLocation = "WEB-INF/wsdl/AddressingService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsa.ServiceIface"
)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
作成されたエンドポイント war アーカイブは以下のエントリから構成されます。
     jar -tvf jaxws-samples-wsa.war 
     0 Mon Apr 21 20:39:30 CEST 2008 META-INF/
   106 Mon Apr 21 20:39:28 CEST 2008 META-INF/MANIFEST.MF
     0 Mon Apr 21 20:39:30 CEST 2008 WEB-INF/
   593 Mon Apr 21 20:39:28 CEST 2008 WEB-INF/web.xml
     0 Mon Apr 21 20:39:30 CEST 2008 WEB-INF/classes/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/
   374 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/ServiceIface.class
   954 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/ServiceImpl.class
     0 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/jaxws/
   703 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/jaxws/SayHello.class
  1074 Mon Apr 21 20:39:26 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsa/jaxws/SayHelloResponse.class
     0 Mon Apr 21 20:39:30 CEST 2008 WEB-INF/wsdl/
  2378 Mon Apr 21 20:39:28 CEST 2008 WEB-INF/wsdl/AddressingService.wsdl
web.xml ファイルの内容は以下のようになります。
  
<?xml version="1.0" encoding="UTF-8"?>

<web-app
   version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
      <servlet-name>AddressingService</servlet-name>
      <servlet-class>org.jboss.test.ws.jaxws.samples.wsa.ServiceImpl</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>AddressingService</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>
通常の JAX-WS クライアントの記述

以下は、Web サービス package.org.jboss.test.ws.jaxws.samples.wsa をルックアップするエンドポイントインターフェースを使用する通常の JAX-WS クライアントです。

package.org.jboss.test.ws.jaxws.samples.wsa:

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

public final class SimpleServiceTestCase
{
   private final String serviceURL = "http://localhost:8080/jaxws-samples-wsa/AddressingService";
   
   public static void main(String[] args) throws Exception
   {
      // create service
      QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsaddressing", "AddressingService");
      URL wsdlURL = new URL(serviceURL + "?wsdl");
      Service service = Service.create(wsdlURL, serviceName);
      ServiceIface proxy = (ServiceIface)service.getPort(ServiceIface.class);
      
      // invoke method
      proxy.sayHello();
   }
   
}
エンドポイントおよびクライアント実装が存在しますが、WS-Addressing は存在しません。次の目標は WS-Addressing 機能を有効にすることです。

5.1. WS-Addressing 1.0 の有効化

JbossWS-CXF で WS-Addressing を有効にするには、2 つの手順があります。
  • サービスエンドポイントを @Addressing アノテーションでアノテートします。
  • JAX-WS Web サービス機能を使用して WS-Addressing を設定するようクライアントを変更します。
WS-Addressing を設定するようエンドポイントコードを更新

この時点で、WS-Addressing を設定するためにエンドポイント実装を更新する必要があります。更新されたエンドポイントコードは以下のとおりです。

 
package org.jboss.test.ws.jaxws.samples.wsa;
 
import javax.jws.WebService;
import javax.xml.ws.soap.Addressing;
 
@WebService
(
   portName = "AddressingServicePort",
   serviceName = "AddressingService",
   wsdlLocation = "WEB-INF/wsdl/AddressingService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsaddressing",
   endpointInterface = "org.jboss.test.ws.jaxws.samples.wsa.ServiceIface"
)
@Addressing(enabled=true, required=true)
public class ServiceImpl implements ServiceIface
{
   public String sayHello()
   {
      return "Hello World!";
   }
}
WS-Addressing を設定するために JAX-WS 2.1 Addressing アノテーションを追加しました。次の手順は、この変更を適用するためにエンドポイントアーカイブを再パッケージ化することです。
WS-Addressing を設定するためにクライアントコードを更新

WS-Addressing を設定するためにクライアント実装を更新する必要があります。更新されたクライアントコードは以下のとおりです。

package org.jboss.test.ws.jaxws.samples.wsa;
 
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.AddressingFeature;
 
public final class AddressingTestCase
{
   private final String serviceURL = "http://localhost:8080/jaxws-samples-wsa/AddressingService";
   
   public static void main(String[] args) throws Exception
   {
      // construct proxy
      QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsaddressing", "AddressingService");
      URL wsdlURL = new URL(serviceURL + "?wsdl");
      Service service = Service.create(wsdlURL, serviceName);
      ServiceIface proxy = (ServiceIface)service.getPort(ServiceIface.class,  new AddressingFeature());
      // invoke method
      proxy.sayHello();
   }
   
}

この時点で、JAX-WS クライアントおよびエンドポイントは WS-Addressing を使用してお互い通信します。

第6章 WS-Reliable Messaging

CXF は 2005 年 2 月版の Web Service Reliable Messaging Protocol 仕様をサポートします。CXF の他のほとんどの機能と同様に、これはインターセプタベースです。WS-Reliable Messaging 実装は、合計で 4 つのインターセプタから構成されます。これらは以下のとおりです。
org.apache.cxf.ws.rm.RMOutInterceptor
役割:
  • CreateSequence 要求を送信します。
  • CreateSequenceResponse 応答を待機します。
  • アプリケーションメッセージのシーケンスプロパティ (id およびメッセージ番号) を収集します。
org.apache.cxf.ws.rm.RMInInterceptor
RM プロトコルメッセージと、アプリケーションメッセージでピギーバックされた SequenceAcknowledgments をインターセプトおよび処理します。
org.apache.cxf.ws.rm.soap.RMSoapInterceptor
RM ヘッダのエンコードとデコード
org.apache.cxf.ws.rm.soap.RetransmissionInterceptor
将来の再送信のためにアプリケーションメッセージのコピーを作成します。
インターセプタベースの QoS

各インターセプタチェーンに RM インターセプタがあると、必要な場合に RM プロトコルメッセージが交換されます。たとえば、送信インターセプタチェーンの最初のアプリケーションメッセージをインターセプトするときに、RMOutInterceptorCreateSequence 要求を送信し、CreateSequenceResponse 応答の受信後に元のアプリケーションメッセージを処理します。また、RM インターセプタはシーケンスヘッダをアプリケーションメッセージに追加し、宛先サイドで、メッセージからシーケンスヘッダを抽出します。

つまり、メッセージ交換の信頼性を高めるためにアプリケーションコードの変更を行う必要はありません。
設定により、シーケンス境界と信頼性の高い交換の他のアスペクトを制御できます。デフォルトでは、CXF はシーケンスのライフタイムを最大化しようとします。これにより、RM プロトコルメッセージによるオーバーヘッドが減少します。ただし、RM シーケンス終了ポリシーのソースを設定 (最大シーケンス長を設定) することにより、1 つのアプリケーションメッセージあたり 1 つの独立したシーケンスを使用することを強制できます。このことと信頼できる交換の他のアスペクト設定の詳細については、7章WS-Reliable Messaging の使用 を参照してください。

第7章 WS-Reliable Messaging の使用

JBoss WS-CXF/CXF において 2 つのポイント間で信頼できるメッセージングを確立するには、CXF RM とアドレスインターセプタをインターセプタチェーンに追加する必要があります。これは、以下に示されたいずれかの方法で実現できます。
RMAssertion および CXF WS-Policy フレームワーク

RM インターセプタは、以下のことが行われた場合にポリシーフレームワークによって各インターセプタチェーンに自動的に追加されます。

  1. RMAssertion 要素を持つポリシーは wsdl:service 要素 (または、WS-Policy 添付のルールに従った、Policy または PolicyReference 要素の添付ポイントである他の WSDL 要素) に添付されます。
  2. CXF WS-Policy フレームワークが有効になります。
アサーション属性はソースまたは宛先の動作を制御します。たとえば、サーバーサイドで WS-Policy フレームワークを有効にする場合、設定ファイルは以下のようになります。
  
<jaxws:endpoint ...>
    <jaxws:features>
        <p:policies/>
    </jaxws:features>
</jaxws:endpoint>
WSDL は以下のようになります。
<wsp:Policy wsu:Id="RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsam:Addressing xmlns:wsam="http://www.w3.org/2007/02/addressing/metadata">
        <wsp:Policy/>
    </wsam:Addressing>
    <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
        <wsrmp:BaseRetransmissionInterval Milliseconds="10000"/> 
    </wsrmp:RMAssertion>
</wsp:Policy>
...
<wsdl:service name="ReliableGreeterService">
    <wsdl:port binding="tns:GreeterSOAPBinding" name="GreeterPort">
        <soap:address location="http://localhost:9020/SoapContext/GreeterPort"/>
        <wsp:PolicyReference URI="#RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"/>        
    </wsdl:port>
</wsdl:service>
PolicyReference を wsdl:port 要素に添付する代わりに、含まれるポリシーの子要素 (サーバーエンドポイントなど) として指定できます。
 
<wsp:Policy wsu:Id="="RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy" ...>
</wsp:Policy>

<jaxws:endpoint ...>
  <jaxws:features> 
	<p:policies>
	  <wsp:PolicyReference URI="#RM" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"/>
	</p:policies>
  </jaxws:features>
</jaxws:endpoint>
信頼できるメッセージング機能の使用

WS-Policy フレームワークを使用しない、シーケンス終了ポリシーや永続ストアなどの追加パラメータを設定しない場合は、ReliableMessaging 機能を使用できます。サポートされる子要素は以下のとおりです。

RMAssertion
タイプ RMAssertion の要素。
deliveryAssurance
適用すべき配信保証を定義するタイプ DeliveryAssuranceType の要素 (AtMostOnceAtLeastOnceInOrder)。
sourcePolicy
RM ソースの詳細 (オファーを CreateSequence 要求またはシーケンス終了ポリシーに常に含める必要があるかどうかなど) を設定できるタイプ SourcePolicyType の要素。
destinationPolicy
RM 宛先の詳細 (受信オファーを受け入れるかどうかなど) を設定できるタイプ DestinationPolicyType の要素。
ストア
使用するストア (デフォルト値: null)。これは、タイプ jdbcStore の要素 (同じネームスペース内)、Bean、または RMStore インターフェースを実装する Bean の参照である必要があります。
jbdcStore 要素タイプは以下のように定義されます。
以下の例はバスレベルで適用されます。
<cxf:bus>
    <cxf:features>
        <wsa:addressing/>
        <wsrm-mgr:reliableMessaging>
            <wsrm-policy:RMAssertion>
                <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>           
                <wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>          
            </wsrm-policy:RMAssertion> 
            <wsrm-mgr:sourcePolicy>
                <wsrm-mgr:sequenceTerminationPolicy maxLength="5"/>                    
            </wsrm-mgr:sourcePolicy>     
            <wsrm-mgr:destinationPolicy acceptOffers="false">            
            <wsrm:store>
               <ref bean="myStore"/>
            </wsrm:store>
        </wsrm-mgr:reliableMessaging>
    </cxf:features>
</cxf:bus>
信頼できるメッセージングストアの設定

永続性を有効にするには、RM の永続ストアを実装するオブジェクトを指定する必要があります。独自のオブジェクトを開発したり、CXF に同梱される JDBC ベースのストア (class org.apache.cxf.ws.rm.persistence.jdbc.RMTxStore) を使用したりできます。JDBC ベースのストアは、カスタム jdbcStore Bean を使用して設定できます。サポートされる属性は以下の表に示されています。

表7.1 属性

属性名 文字列 デフォルト値
driverClassName 文字列 org.apache.derby.jdbc.EmbeddedDriver
userName 文字列 null
passWord 文字列 null
url 文字列 jdbc:derby:rmdb;create=true
例を以下に示します。
  <wsrm-mgr:jdbcStore id="myStore"
    driverClassName="org.apache.derby.jdbc.ClientDriver"
    url="jdbc:derby://localhost:1527/rmdb;create=true"
    password="password"/>
信頼できるメッセージングマネージャを手動で設定

RM マネージャのプロパティを設定するには、RMManager 要素を使用します。同じ子要素は上記の ReliableMessaging 機能としてサポートされます。たとえば、機能を使用せずに、以下のようにシーケンスが最大長を持つように決定できます。

<wsrm-mgr:rmManager xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager">
    <wsrm-mgr:sourcePolicy>
        <wsrm-mgr:sequenceTerminationPolicy maxLength="5"/>                    
    </wsrm-mgr:sourcePolicy>
</wsrm-mgr:rmManager>

第8章 WS-Reliable Messaging チュートリアル

このサンプルでは、WS-Reliable Messaging 1.0 を使用してクライアントおよびエンドポイント通信を作成する方法を示します。WS-RM ベースのサービスとクライアントの作成は非常に単純です。ユーザーは最初に通常の JAX-WS サービスおよびクライアントを作成する必要があります。最後の手順は WS-RM を設定することです。
以下のエンドポイント実装から始めます。
package org.jboss.test.ws.jaxws.samples.wsrm.service;
 
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebService;
 
@WebService
(
   name = "SimpleService",
   serviceName = "SimpleService",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsrm"
)
public class SimpleServiceImpl
{
   @Oneway
   @WebMethod
   public void ping()
   {
      System.out.println("ping()");
   }
 
   @WebMethod
   public String echo(String s)
   {
      System.out.println("echo(" + s + ")");
      return s;
   }
}
コンパイルされたエンドポイントクラスがディレクトリ /home/username/wsrm/cxf/classes に存在するとします。次の手順は JAX-WS アーティファクトおよび WSSDL を生成することです。

8.1. WSDL および JAX-WS エンドポイントアーティファクトの生成

wsprovide コマンドラインツールを使用して WSDL および JAX-WS アーティファクトを生成します。コマンドは以下のとおりです。
cd $JBOSS_HOME/bin
./wsprovide.sh --keep --wsdl \ 
   --classpath=/home/username/wsrm/cxf/classes \
   --output=/home/username/wsrm/cxf/wsprovide/generated/classes \
   --resource=/home/username/wsrm/cxf/wsprovide/generated/wsdl \
   --source=/home/username/wsrm/cxf/wsprovide/generated/src \
   org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl
上記のコマンドは以下のアーティファクトを生成します。
コンパイルされたクラス
Echo.class
Echo response.class
Ping.class
Java ソース
Echo.java
EchoResponse.java
Ping.java
Contract アーティファクト
SimpleService.wsdl
上記で生成されたアーティファクトはエンドポイントアーカイブの一部ですが、エンドポイントアーカイブを作成する前に、生成された WSDL をエンドポイントから参照する必要があります。これを実現するには、wsdlLocation アノテーション属性を使用します。war ファイルにパッケージ化される前に更新されたエンドポイント実装は以下のとおりです。
   
package org.jboss.test.ws.jaxws.samples.wsrm.service;
 
import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebService;
 
@WebService
(
   name = "SimpleService",
   serviceName = "SimpleService",
   wsdlLocation = "WEB-INF/wsdl/SimpleService.wsdl",
   targetNamespace = "http://www.jboss.org/jbossws/ws-extensions/wsrm"
)
public class SimpleServiceImpl
{
   @Oneway
   @WebMethod
   public void ping()
   {
      System.out.println("ping()");
   }
 
   @WebMethod
   public String echo(String s)
   {
      System.out.println("echo(" + s + ")");
      return s;
   }
}
作成されたエンドポイント war アーカイブは以下のエントリから構成されます。
jar -tvf jaxws-samples-wsrm.war 
     0 Wed Apr 16 14:39:22 CEST 2008 META-INF/
   106 Wed Apr 16 14:39:20 CEST 2008 META-INF/MANIFEST.MF
     0 Wed Apr 16 14:39:22 CEST 2008 WEB-INF/
   591 Wed Apr 16 14:39:20 CEST 2008 WEB-INF/web.xml
     0 Wed Apr 16 14:39:22 CEST 2008 WEB-INF/classes/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
     0 Wed Apr 16 14:39:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Wed Apr 16 14:39:20 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/
     0 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/
  1235 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/SimpleServiceImpl.class
   997 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Echo.class
  1050 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/EchoResponse.class
   679 Wed Apr 16 14:39:18 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Ping.class
     0 Wed Apr 16 14:39:22 CEST 2008 WEB-INF/wsdl/
  2799 Wed Apr 16 14:39:20 CEST 2008 WEB-INF/wsdl/SimpleService.wsdl
web.xml ファイルの内容は以下のとおりです。
    
<?xml version="1.0" encoding="UTF-8"?>

<web-app
   version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
      <servlet-name>SimpleService</servlet-name>
      <servlet-class>org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>SimpleService</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>

8.2. JAX-WS クライアントアーティファクトの生成

通常の JAX-WS クライアントを記述する前に、WSDL からクライアントアーティファクトを生成する必要があります。これを実現するコマンドは以下のとおりです。
cd $JBOSS_HOME/bin
./wsconsume.sh --keep \          
   --package=org.jboss.test.ws.jaxws.samples.wsrm.generated \
   --output=/home/username/wsrm/cxf/wsconsume/generated/classes \
   --source=/home/username/wsrm/cxf/wsconsume/generated/src \
   /home/username/wsrm/cxf/wsprovide/generated/wsdl/SimpleService.wsdl
生成されたアーティファクトは以下のとおりです。
コンパイルされたクラス
Echo.class
ObjectFactory.class
Ping.class
SimpleService_Service.class
EchoResponse.class
package-info.class
SimpleService.class
SimpleService_SimpleServicePort_Client.class
Java ソース
Echo.java
ObjectFactory.java
Ping.java
SimpleService_Service.java
EchoResponse.java
package-info.java
SimpleService.java
SimpleService_SimpleServicePort_Client.java
最後の手順は、生成されたアーティファクトを使用して通常の JAX-WS クライアントを記述することです。
通常の JAX-WS クライアントの記述

以下は、生成されたアーティファクトを使用した通常の JAX-WS クライアントです。

package org.jboss.test.ws.jaxws.samples.wsrm.client;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService;

public final class SimpleServiceTestCase
{

   private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService";
   
   public static void main(String[] args) throws Exception
   {
      // create service
      QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService");
      URL wsdlURL = new URL(serviceURL + "?wsdl");
      Service service = Service.create(wsdlURL, serviceName);
      SimpleService proxy = (SimpleService)service.getPort(SimpleService.class);
      
      // invoke methods
      proxy.ping(); // one way call
      proxy.echo("Hello World!"); // request responce call
   }
   
}
この時点で、エンドポイントおよび clinet 実装の両方が存在しますが、WS-Reliable Messaging は使用されません。次の目標は、WS-RM 機能を有効にすることです。

8.3. WS-RM 1.0 の有効化

WS-RM in JBossWS-CXF を有効にするには、以下の 4 つの手順が必要です。
  • WSRM および WS-Addressing ポリシーを含む WS-Policy で WSDL を拡張します。
  • jbossws-cxf.xml エンドポイント設定ファイルを提供します。
  • クライアント CXF 設定を提供します。
  • CXF 設定ファイルを読み取るようクライアントコードを更新します。
WS-Policy を使用して WSDL を更新

WSRM を有効化するには、WSDL を WSRM とアドレスポリシーで拡張する必要があります。以下のようになります。

 
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="SimpleService" targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wsrm" xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wsrm" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://www.w3.org/2006/07/ws-policy">

  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <!-- Created WS-Policy with WSRM addressing assertions -->
  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - -->
  <wsp:UsingPolicy/>
  <wsp:Policy wsu:Id="wsrm10policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wswa:UsingAddressing xmlns:wswa="http://www.w3.org/2006/05/addressing/wsdl">
      <wsp:Policy/>
    <wswa:UsingAddressing>
    <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"/>
  </wsp:Policy>
  
  <wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wsrm" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wsrm">
<xsd:element name="ping" type="tns:ping"/>
<xsd:complexType name="ping">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="echo" type="tns:echo"/>
<xsd:complexType name="echo">
<xsd:sequence>
<xsd:element minOccurs="0" name="arg0" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="echoResponse" type="tns:echoResponse"/>
<xsd:complexType name="echoResponse">
<xsd:sequence>
<xsd:element minOccurs="0" name="return" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
  </wsdl:types>
  <wsdl:message name="echoResponse">
    <wsdl:part name="parameters" element="tns:echoResponse">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="echo">
    <wsdl:part name="parameters" element="tns:echo">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="ping">
    <wsdl:part name="parameters" element="tns:ping">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="SimpleService">
    <wsdl:operation name="ping">
      <wsdl:input name="ping" message="tns:ping">
    </wsdl:input>
    </wsdl:operation>
    <wsdl:operation name="echo">
      <wsdl:input name="echo" message="tns:echo">
    </wsdl:input>
      <wsdl:output name="echoResponse" message="tns:echoResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="SimpleServiceSoapBinding" type="tns:SimpleService">
    <!-- - - - - - - - - - - - - - - - - - - - -->
    <!-- Associated WS-Policy with the binding -->
    <!-- - - - - - - - - - - - - - - - - - - - -->
    <wsp:PolicyReference URI="#wsrm10policy"/>
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="ping">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="ping">
        <soap:body use="literal"/>
      </wsdl:input>
    </wsdl:operation>
    <wsdl:operation name="echo">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="echo">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="echoResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="SimpleService">
    <wsdl:port name="SimpleServicePort" binding="tns:SimpleServiceSoapBinding">
      <soap:address location="http://localhost:9090/hello"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

wsp:UsingPolicy;wsp:Policy 要素と wsp:PolicyReference 要素が WSDL に追加されました。
jbossws-cxf.xml エンドポイント設定ファイルの提供

これは、JBossWS CXF 統合拡張ファイル 3章サーバーサイド統合カスタマイズ です。このケースでは、該当する内容は以下のとおりです。

  
<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xmlns:wsp='http://www.w3.org/2006/07/ws-policy'
  xmlns:p='http://cxf.apache.org/policy'
  xsi:schemaLocation='http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://cxf.apache.org/policy
    http://cxf.apache.org/schemas/policy.xsd 
    http://www.w3.org/2006/07/ws-policy
    http://www.w3.org/2006/07/ws-policy.xsd
    http://cxf.apache.org/jaxws
    http://cxf.apache.org/schemas/jaxws.xsd'>
  
  <wsp:Policy wsu:Id="wsrm10policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wswa:UsingAddressing xmlns:wswa="http://www.w3.org/2006/05/addressing/wsdl"/>
    <wsrmp:RMAssertion xmlns:wsrmp="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"/>
  </wsp:Policy>
  
  <jaxws:endpoint
    id='SimpleServiceImpl'
    address='http://localhost:8080/jaxws-samples-wsrm'
    implementor='org.jboss.test.ws.jaxws.samples.wsrm.service.SimpleServiceImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerJSE'/>
    </jaxws:invoker>
    <jaxws:features>
      <p:policies>
        <wsp:PolicyReference URI="#wsrm10policy" xmlns:wsp="http://www.w3.org/2006/07/ws-policy"/>
      </p:policies>
    </jaxws:features>
  </jaxws:endpoint>
  
</beans>

POJO デプロイメントを作成するため、jbossws-cxf.xml CXF 設定ファイルをエンドポイントの WEB-INF ディレクトリに含める必要があります。
jar -tvf jaxws-samples-wsrm.war 
     0 Wed Apr 16 19:05:38 CEST 2008 META-INF/
   106 Wed Apr 16 19:05:36 CEST 2008 META-INF/MANIFEST.MF
     0 Wed Apr 16 19:05:38 CEST 2008 WEB-INF/
   591 Wed Apr 16 19:05:36 CEST 2008 WEB-INF/web.xml
     0 Wed Apr 16 19:05:38 CEST 2008 WEB-INF/classes/
     0 Wed Apr 16 19:05:32 CEST 2008 WEB-INF/classes/org/
     0 Wed Apr 16 19:05:32 CEST 2008 WEB-INF/classes/org/jboss/
     0 Wed Apr 16 19:05:32 CEST 2008 WEB-INF/classes/org/jboss/test/
     0 Wed Apr 16 19:05:32 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
     0 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
     0 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/
     0 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/
     0 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/
  1235 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/SimpleServiceImpl.class
   997 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Echo.class
  1050 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/EchoResponse.class
   679 Wed Apr 16 19:05:34 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsrm/service/jaxws/Ping.class
  1554 Wed Apr 16 19:05:36 CEST 2008 WEB-INF/jbossws-cxf.xml
     0 Wed Apr 16 19:05:38 CEST 2008 WEB-INF/wsdl/
  3237 Wed Apr 16 19:05:36 CEST 2008 WEB-INF/wsdl/SimpleService.wsdl
次の手順はクライアントで使用されるクライアント CXF 設定ファイルを作成することです。CXF クライアントに対して WS-RM クライアントが有効化されます。サンプルでは、このファイルに cxf.xml という名前を付けます。このファイルに内容は以下のとおりです。
     
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cxf="http://cxf.apache.org/core"
  xmlns:wsa="http://cxf.apache.org/ws/addressing"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:wsrm-policy="http://schemas.xmlsoap.org/ws/2005/02/rm/policy"
  xmlns:wsrm-mgr="http://cxf.apache.org/ws/rm/manager"
  xsi:schemaLocation="
    http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    http://cxf.apache.org/transports/http/configuration
    http://cxf.apache.org/schemas/configuration/http-conf.xsd
    http://schemas.xmlsoap.org/ws/2005/02/rm/policy
    http://schemas.xmlsoap.org/ws/2005/02/rm/wsrm-policy.xsd
    http://cxf.apache.org/ws/rm/manager
    http://cxf.apache.org/schemas/configuration/wsrm-manager.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">
 
  <cxf:bus>
    <cxf:features>
      <cxf:logging/>
      <wsa:addressing/>
      <wsrm-mgr:reliableMessaging>
        <wsrm-policy:RMAssertion>
          <wsrm-policy:BaseRetransmissionInterval Milliseconds="4000"/>           
          <wsrm-policy:AcknowledgementInterval Milliseconds="2000"/>          
        </wsrm-policy:RMAssertion>
        <wsrm-mgr:destinationPolicy>
          <wsrm-mgr:acksPolicy intraMessageThreshold="0" />
        </wsrm-mgr:destinationPolicy>
      </wsrm-mgr:reliableMessaging>
    </cxf:features>
  </cxf:bus>
    
</beans>

クライアント設定はクライアントクラスローダーにより取得する必要があります。これを実現するには、cxf.xml をクライアント jar の META-INF ディレクトリに含めます。この jar は、クラスローダーの設定時に提供する必要があります。
また、バス設定をプログラムを使用して読み取ることもできます。
バス設定ファイルを読み取るようクライアントコードを更新

更新された CXF クライアントの最後の部分は以下のとおりです。

  
package org.jboss.test.ws.jaxws.samples.wsrm.client;
 
import java.net.URL;
import java.io.File;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.bus.spring.SpringBusFactory;
import org.jboss.test.ws.jaxws.samples.wsrm.generated.SimpleService;
 
public final class SimpleServiceTestCase
{
 
   private static final String serviceURL = "http://localhost:8080/jaxws-samples-wsrm/SimpleService";
   
   public static void main(String[] args) throws Exception
   {
      // create bus
      SpringBusFactory busFactory = new SpringBusFactory();
      URL cxfConfig = new File("resources/jaxws/samples/wsrm/cxf.xml").toURL();
      Bus bus = busFactory.createBus(cxfConfig);
      busFactory.setDefaultBus(bus);
 
      // create service
      QName serviceName = new QName("http://www.jboss.org/jbossws/ws-extensions/wsrm", "SimpleService");
      URL wsdlURL = new URL(serviceURL + "?wsdl");
      Service service = Service.create(wsdlURL, serviceName);
      SimpleService proxy = (SimpleService)service.getPort(SimpleService.class);
      
      // invoke methods
      proxy.ping(); // one way call
      proxy.echo("Hello World!"); // request responce call
 
      // shutdown bus
      bus.shutdown(true);
   }
   
}

第9章 WS ポリシーフレームワーク

各メッセージに対する効果的なポリシーの計算とそのポリシーの代替がサポートされることの確認は、インターセプタで行われます。

9.1. ポリシー機能の使用

ポリシー機能は以下の属性をサポートします。
ignoreUnknownAssertions
AssertionBuilders が登録されていないアサーションを検出したときに例外をスローすることを示します (デフォルト値:true)。false に設定されると、警告がログに記録されます。
namespace
WS-Policy フレームワーク仕様のネームスペース (デフォルト値: http://www.w3.org/ns/ws-policy)。
この要素は以下の子要素もサポートします。
alternativeSelector
org.apache.cxf.ws.policy.selector.AlternativeSelector インターフェースを実装する Bean または Bean への参照。デフォルトセレクタは最小の代替 (つまり、アサーションの数が最小のもの) を選択します。
また、要素は任意の数の Policy または PolicyReference 子要素を持つことができます。これは Policy または PolicyReference 要素が、機能が適用されたクライアントまたはサーバーエンドポイントの WSDL 契約の wsdl:port 要素に添付されたのと同じ効果があります (または、機能がバスに適用された場合はすべてのエンドポイントに対して)。
たとえば、この機能をバスに適用し、未知のアサーションの検出時に例外がスローされることを防ぐには、以下のようになります。
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:cxf="http://cxf.apache.org/core"
       xmlns:p="http://cxf.apache.org/policy"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/policy http://cxf.apache.org/schemas/policy.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <cxf:bus>
        <cxf:features>
            <p:policies ignoreUnknownAssertions="true"/>
        </cxf:features>
    </cxf:bus>
</beans>

9.2. 外部添付の場所の指定

特定のメッセージに適用するポリシーを集約するときにポリシーフレームワークが考慮すべき外部添付の場所を指定するには、同じネームスペースで <externalAttachment> 要素を使用します。以下の属性がサポートされます。
location
外部添付ドキュメントの場所。これは http://static.springsource.org/spring/docs/2.0.x/reference/resources.html タイププロパティの形式を取ります (たとえば、classpath:etc/policies.xmlfile:///x1/resources/polcies.xml)。
例を以下に示します。
<p:externalAttachment location="classpath:org/apache/cxf/systest/ws/policy/addr-external.xml"/>
設定ファイルでは、任意の数の <externalAttachment> 要素を指定できます。

第10章 WS-Security

WS-Security を使用すると、HTTPS などのトランスポートレベルプロトコルを超えたサービスをセキュアにできます。XML-Encryption や WS-Security 標準で定義されたヘッダなどの標準を介して、以下のことを行えます。
  • サービス間で認証トークンを受け渡します。
  • メッセージまたはメッセージの一部を暗号化します。
  • メッセージを署名します。
  • メッセージをタイムスタンプします。
現在、CXF は WSS4J を統合して WS-Security を実装します。統合を使用するには、これらのインターセプタを設定し、サービスまたはクライアントにそれぞれ追加する必要があります。

10.1. 暗号化と署名の概要

WS-Security ではパブリックおよびプライベートキー暗号化を頻繁に使用します。WS-Security の設定方法をよく理解するにはこれらの基本を理解することが役に立ちます。これらは大きいプライム番号およびキー機能を使用して生成されます。
キーは数学的に関連しますが、お互いから派生することはできません。これらのキーを使用すると、メッセージを暗号化できます。たとえば、Bob が Alice にメッセージを送信する場合、Bob は Alice のパブリックキーを使用してメッセージを暗号化できます。Alice は自分のプライベートキーを使用してこのメッセージを復号化できます。Alice のみがプライベートキーを持っているため、このメッセージを復号化できるのは Alice だけです。
また、メッセージは署名することもできます。これにより、メッセージの信憑性が確認されます。Alice がメッセージを Bob に送信し、Bob がそのメッセージが Alice から送信されたことを確認する場合、Alice はプライベートキーを使用してメッセージを署名できます。Bob はパブリックキーを使用してメッセージが Alice から送信されたことを確認できます。

第11章 JBoss での WSS4J セキュリティ

この短い章では JBossWS-CXF で 10章WS-Security を使用する方法を説明します。ここでは、単純なアプリケーションの作成方法と JBoss で WSS4J セキュリティを利用するために実行する必要があることについて説明します。

11.1. Web サービスエンドポイントの作成

最初に、JAX-WS を使用して Web サービスエンドポイントまたはクライアントを作成する必要があります。これは、多くの方法で実現できます。たとえば、以下の手順を実行します。
  1. エンドポイント実装を記述し、サービス契約を生成する wsprovide JBoss コマンドラインツールを実行します。
  2. wsconsume JBoss コマンドラインツールを実行してサービス契約からクライアントアーティファクトを取得します (トップダウン方式)。
  3. クライアント実装を記述します。

11.2. WS-Security の有効化

WSS4J セキュリティが、サービスとクライアントに個々に追加された、または必要に応じて追加されたインターセプタからトリガされます。これらのインターセプタでは、ほとんどの一般的な WS-Security 関連プロセスを実行できます。
  • サービス間で認証トークンを受け渡します。
  • メッセージまたはメッセージの一部を暗号化します。
  • メッセージを署名します。
  • メッセージをタイムスタンプします。
インターセプタは、プログラムを使用するか、あるいはエンドポイントの Spring xml 設定を使用して追加できます。たとえば、サーバー側では、以下のように jbossws-cxf.xml ファイルで署名と暗号化を設定できます。
 
<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://cxf.apache.org/jaxws
    http://cxf.apache.org/schemas/jaxws.xsd'>
  
  <bean id="Sign_Request" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="Timestamp Signature Encrypt"/>
        <entry key="signaturePropFile" value="bob.properties"/>
        <entry key="decryptionPropFile" value="bob.properties"/>
        <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback"/>
      </map>
    </constructor-arg>
  </bean>
  
  <bean id="Sign_Response" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
    <constructor-arg>
      <map>
        <entry key="action" value="Timestamp Signature Encrypt"/>
        <entry key="user" value="bob"/>
        <entry key="signaturePropFile" value="bob.properties"/>
        <entry key="encryptionPropFile" value="bob.properties"/>
        <entry key="encryptionUser" value="Alice"/>
        <entry key="signatureKeyIdentifier" value="DirectReference"/>
        <entry key="passwordCallbackClass" value="org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback"/>
        <entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
        <entry key="encryptionParts" value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
        <entry key="encryptionKeyTransportAlgorithm" value="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <entry key="encryptionSymAlgorithm" value="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
      </map>
    </constructor-arg>
   </bean>
  
  <jaxws:endpoint
    id='ServiceImpl'
    address='http://@jboss.bind.address@:8080/jaxws-samples-wsse-sign-encrypt'
    implementor='org.jboss.test.ws.jaxws.samples.wsse.ServiceImpl'>
    <jaxws:invoker>
      <bean class='org.jboss.wsf.stack.cxf.InvokerJSE'/>
    </jaxws:invoker>
    <jaxws:outInterceptors>
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
        <ref bean="Sign_Response"/>
    </jaxws:outInterceptors>
    <jaxws:inInterceptors>
        <ref bean="Sign_Request"/>
        <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
    </jaxws:inInterceptors>
  </jaxws:endpoint>
</beans>
これは、全体のセキュリティ設定 (アルゴリズムと署名または暗号化する要素を含む) を指定します。また、キーストア関連情報を提供するプロパティファイル (bob.properties) を参照します。
 
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=password
org.apache.ws.security.crypto.merlin.keystore.alias=bob
org.apache.ws.security.crypto.merlin.file=bob.jks
上記の jbossws-cxf.xml ファイルで確認できるように、キーストアパスワードコールバックハンドラも設定されます。プロパティファイルにキーストアのパスワードが含まれる場合、このコールバックハンドラは各キーのパスワードを設定するために使用されます (これは各キーがストアにインポートされたときに使用されるものと一致する必要があります)。以下に例を示します。
package org.jboss.test.ws.jaxws.samples.wsse;
 
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
 
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
 
public class KeystorePasswordCallback implements CallbackHandler
{
   private Map<String, String> passwords = new HashMap<String, String>();
 
   public KeystorePasswordCallback()
   {
      passwords.put("alice", "password");
      passwords.put("bob", "password");
   }
 
   public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
   {
      for (int i = 0; i < callbacks.length; i++)
      {
         WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
         String pass = passwords.get(pc.getIdentifer());
         if (pass != null)
         {
            pc.setPassword(pass);
            return;
         }
      }
   }
 
   public void setAliasPassword(String alias, String password)
   {
      passwords.put(alias, password);
   }
}
クライアントサイドで、同様にプログラムを使用してインターセプタを設定できます。以下に、上述したエンドポイントのクライアントの一部を示します。
Endpoint cxfEndpoint = client.getEndpoint();
Map<String,Object> outProps = new HashMap<String,Object>();
outProps.put("action", "Timestamp Signature Encrypt");
outProps.put("user", "alice");
outProps.put("signaturePropFile", "META-INF/alice.properties");
outProps.put("signatureKeyIdentifier", "DirectReference");
outProps.put("passwordCallbackClass", "org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback");
outProps.put("signatureParts", "{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put("encryptionPropFile", "META-INF/alice.properties");
outProps.put("encryptionUser", "Bob");
outProps.put("encryptionParts", "{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body");
outProps.put("encryptionSymAlgorithm", "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
outProps.put("encryptionKeyTransportAlgorithm", "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps); //request
cxfEndpoint.getOutInterceptors().add(wssOut);
cxfEndpoint.getOutInterceptors().add(new SAAJOutInterceptor());
      
Map<String,Object> inProps= new HashMap<String,Object>();
inProps.put("action", "Timestamp Signature Encrypt");
inProps.put("signaturePropFile", "META-INF/alice.properties");
inProps.put("passwordCallbackClass", "org.jboss.test.ws.jaxws.samples.wsse.KeystorePasswordCallback");
inProps.put("decryptionPropFile", "META-INF/alice.properties");
WSS4JInInterceptor wssIn = new WSS4JInInterceptor(inProps); //response
cxfEndpoint.getInInterceptors().add(wssIn);
cxfEndpoint.getInInterceptors().add(new SAAJInInterceptor());

11.2.1. パッケージおよびデプロイ

Web サービスエンドポイントをデプロイするには、サービス実装と WSDL 契約とともに以下のファイルをパッケージ化する必要があります。
  1. jbossws-cxf.xml 記述子。
  2. プロパティファイル。
  3. キーストアファイル (署名/暗号化に必要な場合)。
  4. キーストアパスワードコールバックハンドラクラス。
たとえば、以前に記述した署名および暗号化サンプル (POJO エンドポイント) のアーカイブ内容は以下のようになります。
[cxf-tests]$ jar -tvf target/test-libs/jaxws-samples-wsse-sign-encrypt.war 
   0 Tue Jun 03 19:41:26 CEST 2008 META-INF/
 106 Tue Jun 03 19:41:24 CEST 2008 META-INF/MANIFEST.MF
   0 Tue Jun 03 19:41:26 CEST 2008 WEB-INF/
   0 Tue Jun 03 19:41:26 CEST 2008 WEB-INF/classes/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
1628 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/KeystorePasswordCallback.class
 364 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/ServiceIface.class
 859 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/ServiceImpl.class
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/jaxws/
 685 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/jaxws/SayHello.class
1049 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/jaxws/SayHelloResponse.class
2847 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/jbossws-cxf.xml
   0 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/wsdl/
1575 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/wsdl/SecurityService.wsdl
 641 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/wsdl/SecurityService_schema1.xsd
1820 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/bob.jks
 311 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/classes/bob.properties
 573 Tue Jun 03 19:41:24 CEST 2008 WEB-INF/web.xml
クライアントサイドで、代わりにプロパティおよびキーストアファイルのみが必要です (インターセプタをプログラムで設定することを前提)。WS-Security 対応アプリケーションをデプロイおよびテストする必要があります。

11.3. WS-Security ポリシー

JBossWS-CXF には、CXF WS-Security ポリシー実装も含まれます。このポリシー実装を使用すると WS-Security を簡単に設定できます。クライアントまたは jbossws-cxf.xml 記述子でインターセプタを手動で設定する代わりに、WSDL 契約で適切なポリシーを提供します。
 ...
  <binding name="SecurityServicePortBinding" type="tns:ServiceIface">
    <wsp:PolicyReference URI="#SecurityServiceSignPolicy"/>
  ...
  <wsp:Policy wsu:Id="SecurityServiceSignPolicy"
    xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
    <wsp:ExactlyOne>
        <wsp:All>
            <sp:AsymmetricBinding xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
                <wsp:Policy>
                    <sp:InitiatorToken>
                        <wsp:Policy>
                            <sp:X509Token sp:IncludeToken='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient'>
                                <wsp:Policy>
                                    <sp:WssX509V3Token10 />
                                </wsp:Policy>
                            </sp:X509Token>
                        </wsp:Policy>
                    </sp:InitiatorToken>
                    <sp:RecipientToken>
                        <wsp:Policy>
                            <sp:X509Token sp:IncludeToken='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always'>
                                <wsp:Policy>
                                    <sp:WssX509V3Token10 />
                                </wsp:Policy>
                            </sp:X509Token>
                        </wsp:Policy>
                    </sp:RecipientToken>
                    <sp:AlgorithmSuite>
                        <wsp:Policy>
                            <sp:Basic256 />
                        </wsp:Policy>
                    </sp:AlgorithmSuite>
                    <sp:Layout>
                        <wsp:Policy>
                            <sp:Strict />
                        </wsp:Policy>
                    </sp:Layout>
                    <sp:OnlySignEntireHeadersAndBody />
                </wsp:Policy>
            </sp:AsymmetricBinding>
            <sp:Wss10 xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
                <wsp:Policy>
                    <sp:MustSupportRefEmbeddedToken />
                </wsp:Policy>
            </sp:Wss10>
            <sp:SignedParts xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolicy'>
                <sp:Body />
            </sp:SignedParts>
        </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
  ...
また、いくつかのプロパティを、メッセージコンテキストまたは jbossws-cxf.xml 記述子で設定する必要があります。
  1. ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());
  2. ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/alice.properties"));
  3. ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/alice.properties"));
<beans
  xmlns='http://www.springframework.org/schema/beans'
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:beans='http://www.springframework.org/schema/beans'
  xmlns:jaxws='http://cxf.apache.org/jaxws'
  xsi:schemaLocation='http://cxf.apache.org/core
    http://cxf.apache.org/schemas/core.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://cxf.apache.org/jaxws
    http://cxf.apache.org/schemas/jaxws.xsd'>
  
  <jaxws:endpoint
    id='ServiceImpl'
    address='http://@jboss.bind.address@:8080/jaxws-samples-wssePolicy-sign'
    implementor='org.jboss.test.ws.jaxws.samples.wssePolicy.ServiceImpl'>
    
    <jaxws:properties>
       <entry key="ws-security.signature.properties" value="bob.properties"/>
       <entry key="ws-security.encryption.properties" value="bob.properties"/>
       <entry key="ws-security.callback-handler" value="org.jboss.test.ws.jaxws.samples.wssePolicy.KeystorePasswordCallback"/>
    </jaxws:properties>
  </jaxws:endpoint>
</beans>

11.4. 認証

いくつかの利用可能なメソッドを用いてWeb サービスのユーザーを認証する方法については、本章を参照してください。

タスク:Web サービスユーザーの認証

タスクの概要

以下の手順にて、JBossWS を用いて Web サービスユーザーを認証する方法について説明しています。
  1. ステートレスセション Bean へのセキュアなアクセス

    @RolesAllowed@PermitAll@DenyAll を用いステートレスセッション Bean にセキュアな状態でアクセス
    認証済みのユーザーにbean クラスおよびビジネスメソッドのいずれかにおいて上記のアノテーションを用いてロール設定が可能です。
    @Stateless
    @RolesAllowed("friend")
    public class EndpointEJB implements EndpointInterface
    {
      ...
    }
  2. POJO エンドポイントのセキュリティ確保

    Secure Plain Old Java Object (POJO) エンドポイント (アプリケーションの WEB-INF/web.xml ファイルで<security-constraint> を定義します)。<auth-constraint> <role-name> 要素は認証が必須かどうかを指定します。 <role-name> 要素にアスタリスクの値を指定することで "not required" に設定することができます。
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>All resources</web-resource-name>
        <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
        <role-name>friend</role-name>
      </auth-constraint>
    </security-constraint>
    
    <security-role>
      <role-name>friend</role-name>
    </security-role>
  3. EJB3 エンドポイントに対するセキュリティードメインの定義

    @SecurityDomain アノテーションを追加することでセキュリティードメインを宣言します。
    @Stateless
    @SecurityDomain("JBossWS")
    @RolesAllowed("friend")
    public class EndpointEJB implements EndpointInterface
    {
      ...
    }
    • また、JBOSS_HOME/server/PROFILE/deploy/jbossws.sar/jboss-management.war/WEB-INF/jboss-web.xml を変更し、セキュリティドメインを指定することもできます。
      <jboss-web>
        <security-domain>JBossWS</security-domain>
      </jboss-web>

    注記

    セキュリティドメインの詳細情報については、『JBoss セキュリティガイド』を参照してください。
  4. POJO エンドポイントに対するセキュリティードメインの定義

    JBOSS_HOME/server/PROFILE/deploy/jbossws.sar/jboss-management.war/WEB-INF/jboss-web.xml を変更し、セキュリティドメインを指定します。
                <jboss-web>
                <security-domain>JBossWS</security-domain>
                </jboss-web>
    
  5. セキュリティコンテキストの定義

    JBOSS_HOME/server/PROFILE/conf/login-config.xml ファイルでセキュリティコンテキストを定義します。
    <!-- 
        A template configuration for the JBossWS security domain.
        This defaults to the UsersRolesLoginModule the same as other and should be
        changed to a stronger authentication mechanism as required.
    -->
    <application-policy name="JBossWS">
      <authentication>
        <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
          <module-option name="usersProperties">props/jbossws-users.properties</module-option>
          <module-option name="rolesProperties">props/jbossws-roles.properties</module-option>
          <module-option name="unauthenticatedIdentity">anonymous</module-option>
        </login-module>
      </authentication>
    </application-policy>

    注記

    デフォルトのJBOSS_HOME/server/PROFILE/conf/login-config.xml は、貴社のデプロイメントに適したセキュリティを提供する別のログインモジュールに変更する必要があります。LdapLoginModule を使ったユーザー認証制御の方法については、タスク:LDAP認証の有効化 に従ってください。
  6. EJB3 エンドポイントに対して HTTP の基本的な認証を定義

    Bean クラスで @WebContext アノテーションを使用します。
                @Stateless
                @SecurityDomain("JBossWS")
                @RolesAllowed("friend")
                @WebContext(contextRoot="/my-cxt", urlPattern="/*", authMethod="BASIC", transportGuarantee="NONE", secureWSDLAccess=false)
                public class EndpointEJB implements EndpointInterface
                {
                  ...
                }
    
  7. POJO エンドポイントに対して HTTP の基本的な認証を定義

    使用している Web アプリケーションの WEB-INF/web.xml に追加
                <login-config>
                  <auth-method>BASIC</auth-method>
                  <realm-name>Test Realm</realm-name>
                </login-config>
    
  8. クライアントサイド - ユーザー名とパスワードを設定

    Web サービスクライアントはjavax.xml.ws.BindingProvider インターフェースを利用し、ユーザー名やパスワードの組み合わせを設定できます。
                URL wsdlURL = new File("resources/jaxws/samples/context/WEB-INF/wsdl/TestEndpoint.wsdl").toURL();
                QName qname = new QName("http://org.jboss.ws/jaxws/context", "TestEndpointService");
                Service service = Service.create(wsdlURL, qname);
                port = (TestEndpoint)service.getPort(TestEndpoint.class);
                 
                BindingProvider bp = (BindingProvider)port;
                bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "jsmith");
                bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "PaSSw0rd");
    
  9. クライアントサイド - WSDL によるセキュリティー保護

    java.net.Authenticator を使用して wsdl ファイルへのアクセス時にユーザー名とパスワードを設定します。
                Authenticator.setDefault(new Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username,password.toCharArray());
                    }
                });
                Service service = Service.create(wsdlURL, qname);
    

タスク:LDAP認証の有効化

タスクの概要

このタスクに従い JBossWS アプリケーションに対し Lightweight Directory Access Protocol (LDAP)認証を設定します。『JBoss セキュリティガイド』の記載どおりLdapLoginModuleを使います。
初期設定は タスク:Web サービスユーザーの認証 と同様です。
  1. ステートレスセション Bean へのセキュアなアクセス

    @RolesAllowed@PermitAll@DenyAll を用いステートレスセッション Bean にセキュアな状態でアクセス
    認証済みのユーザーにbean クラスおよびビジネスメソッドのいずれかにおいて上記のアノテーションを用いてロール設定が可能です。
    @Stateless
    @RolesAllowed("friend")
    public class EndpointEJB implements EndpointInterface
    {
      ...
    }
  2. POJO エンドポイントのセキュリティ確保

    同アプリケーションのWEB-INF/web.xml ファイルにある<security-constraint> を定義して、Plain Old Java Object (POJO) エンドポイントのセキュリティを確保
    <auth-constraint> <role-name> 要素は認証が必須かを指定します。 <role-name> 要素にアスタリスク (*) 値を指定することで"not required" を設定することができます。
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>All resources</web-resource-name>
        <url-pattern>/*</url-pattern>
      </web-resource-collection>
      <auth-constraint>
        <role-name>*</role-name>
      </auth-constraint>
    </security-constraint>
    
    <login-config>
      <auth-method>BASIC</auth-method>
      <realm-name>JbossWS</realm-name>
    </login-config>

    注記

    有効な<auth-method> 値の詳細情報は、『JBoss Security Guide』の 「Web コンテンツのセキュリティ制限」の項を参照してください。
  3. セキュリティドメインの定義

    @SecurityDomain アノテーションを追加することでセキュリティードメインを宣言します。
    @Stateless
    @SecurityDomain("JBossWS")
    @RolesAllowed("friend")
    public class EndpointEJB implements EndpointInterface
    {
      ...
    }
    • また、JBOSS_HOME/server/PROFILE/deploy/jbossws.sar/jboss-management.war/WEB-INF/jboss-web.xml を変更し、セキュリティドメインを指定することもできます。
      <jboss-web>
        <security-domain>JBossWS</security-domain>
      </jboss-web>

    注記

    セキュリティドメインの詳細情報については、『JBoss セキュリティガイド』を参照してください。
  4. セキュリティコンテキストの定義

    JBOSS_HOME/server/PROFILE/conf/login-config.xml ファイルでセキュリティコンテキストを定義します。
                <application-policy name="JBossWS">
                  <authentication>
                    <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required">
                       <module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
                       <module-option name="java.naming.provider.url">ldap://ldaphost.jboss.org:1389/</module-option>
                       <module-option name="java.naming.security.authentication">simple</module-option>
                       <module-option name="principalDNPrefix">uid=</module-option>
                       <module-option name="principalDNSuffix">,ou=People,dc=jboss,dc=org</module-option>
                       <module-option name="rolesCtxDN">ou=Roles,dc=jboss,dc=org</module-option>
                       <module-option name="uidAttributeID">member</module-option>
                       <module-option name="matchOnUserDN">true</module-option>
                       <module-option name="roleAttributeID">cn</module-option>
                       <module-option name="roleAttributeIsDN">false </module-option>
                    </login-module>
                  </authentication>
                </application-policy>
    

    注記

    LdapLoginModule やその他の利用可能なログインモジュールに関する情報はセキュリティガイドを参照してください。

11.5. その他の情報

11.5.1. サンプル

JBossWS-CXF ソースディストリビューションには、X.509 証明書署名および暗号化と Username Token Profile を使用した複数のサンプルが含まれます。これらはパッケージ org.jboss.test.ws.jaxws.samples.wsse に含まれます。

11.5.2. ユーザー名/パスワード設定

Username Token Profile を使用する場合、ユーザー名とパスワードは提供する必要があるコールバックハンドラを介して提供および検証されます。キーストアパスワードコールバックハンドラとして、javax.security.auth.callback.CallbackHandler を実装する必要があります。これらは、 passwordCallbackClass 属性を介して jbossws-cxf.xml (またはプログラムを使用) で設定されます。

11.5.3. 暗号化アルゴリズム

暗号化が必要な場合は、Apache CXF が使用する暗号化アルゴリズムをサポートする追加の JCE プロバイダをインストールする必要があることがあります。通常、これは Bouncy Castle プロバイダを Java Runtime Environment ( JRE ) で設定する必要があることを意味します。この詳細については、『『管理および設定ガイド (Administration and Configuration guide)』』の項「BouncyCastle JCE プロバイダのインストール (Installing the BouncyCastle JCE provider)」を参照してください。

第12章 SOAP メッセージロギング

cxf-extension-jbossws.xml ファイルには、Apache CXF スタックに対する JBossWS 拡張が含まれます。このファイルを手動で追加し、cxf.extensions ファイルでリンクする必要があります。cxf-extension-jbossws-xml で、以下のものを有効にする必要があります。
  <cxf:bus>
    <cxf:inInterceptors>
      <ref bean="logInbound"/>
    </cxf:inInterceptors>
    <cxf:outInterceptors>
      <ref bean="logOutbound"/>
    </cxf:outInterceptors>
    <cxf:inFaultInterceptors>
      <ref bean="logOutbound"/>
    </cxf:inFaultInterceptors>
  </cxf:bus>
cxf-extension-jbossws.xml の内容をコメント解除した後で、jar または zip を再圧縮する必要があります。また、Apache CXF は SOAP メッセージロギングを設定する複数の方法を提供します。プログラムによる設定の場合、SEI または SEI 実装クラスで以下のアノテーションを使用できます。SEI に配置された場合は、クライアントとサーバーに対してロギングが有効化されます。SEI 実装クラスに配置された場合、これらはサーバーサイドロギングに対してのみ重要になります。
    
@javax.jws.WebService(portName = "MyWebServicePort", serviceName = "MyWebService", ...)
@Features(features = "org.apache.cxf.feature.LoggingFeature")        
public class MyWebServicePortTypeImpl implements MyWebServicePortType {

これは以下と同等:
import org.apache.cxf.interceptor.InInterceptors;
import org.apache.cxf.interceptor.OutInterceptors;

@javax.jws.WebService(portName = "WebServicePort", serviceName = "WebServiceService", ...)
@InInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingInInterceptor")
@OutInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingOutInterceptor")
public class WebServicePortTypeImpl implements WebServicePortType {
プログラムによるクライアントサイドロギングの場合は、例として以下のコード断片を使用できます。
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;

public class WSClient {
    public static void main (String[] args) {
        MyService ws = new MyService();
        MyPortType port = ws.getPort();
        
        Client client = ClientProxy.getClient(port);
        client.getInInterceptors().add(new LoggingInInterceptor());
        client.getOutInterceptors().add(new LoggingOutInterceptor()); 
        
        // make WS calls...
最後に、ロギング機能を使用してメッセージロギングを有効にすることもできます。
        
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:cxf="http://cxf.apache.org/core"
      xsi:schemaLocation="
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <cxf:bus>
        <cxf:features>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus> 
</beans>

12.1. デバッグツール

交換されたメッセージを取得するために使用できるツールは以下のとおりです。
Tcpmon
TCPMon を使用すると、送受信されるメッセージを簡単に確認できます。
WSMonitor
WSMonitor は Tcpmon の別のオプションですが、機能が若干追加されます。
SOAP UI
SOAP UI はデバッグにも使用できます。メッセージを確認する以外に、メッセージを送信し、サービスをロードテストできます。これには、Eclipse、IDEA、および NetBeans のプラグインも含まれます。
Wireshark
ネットワークパケットアナライザである WiresharkSOAP メッセージのルーティングを追跡するのに役に立ちます。非 SOAP エラーメッセージを確認できることにより、これは、CXF クライアントが通常処理できない HTML エラーメッセージをサーバーから取得するときにも役に立ちます。

付録A 改訂履歴

改訂履歴
改訂 5.1.2-2.4002013-10-31Rüdiger Landmann
Rebuild with publican 4.0.0
改訂 5.1.2-22012-07-18Anthony Towns
Rebuild for Publican 3.0
改訂 5.1.2-100Thu 8 December 2011Russell Dickenson
JBoss Enterprise Application Platform 5.1.2 GA に対する変更が反映されています。本ガイドの内容の変更については、『リリースノート 5.1.2』 を参照してください。

法律上の通知

Copyright © 2011 Red Hat, Inc.
This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3.0 Unported License. If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. and provide a link to the original. If the document is modified, all Red Hat trademarks must be removed.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.