Web サービス CXF ユーザーガイド
JBoss Enterprise Application Platform 5 向け
エディッション 5.1.2
Alessio Soldano
asoldano@redhat.com
概要
第1章 はじめに
- 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章 インストール
警告
手順2.1 CXF のインストール
インストーラをダウンロードします。
jboss-ep-ws-cxf-5.1.0-installer.zip
をダウンロードし、Platform インストールのルートの直下にあるホーム jboss-as ディレクトリで解凍します。WS ネイティブを WS CXF と置き換えます。
作成されたディレクトリjbossws-cxf-installer
でant
を実行します。
注記
http://localhost:8080/jbossws
にある JBossWS にアクセスできる必要があります。
第3章 サーバーサイド統合カスタマイズ
- ファイル名は
jbossws-cxf.xml
である必要があります。 - POJO デプロイメントの場合は、
WEB-INF
ディレクトリに含まれます。 - EJB3 デプロイメントの場合は、
META-INF
ディレクトリに含まれます。
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>
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>
注記
org.jboss.wsf.stack.cxf.InvokerJSE
または org.jboss.wsf.stack.cxf.InvokerEJB3 JAX-WS
起動プログラム Bean を参照する必要があります。
第4章 WS Addressing
4.1. JAX-WS を使用して 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 の使用
<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 id="{your.service.namespace}YourPortName"> <jaxws:features> <wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/> </jaxws:features> </jaxws:client>
第5章 Addressing のチュートリアル
以下のエンドポイント実装から始めます。
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 を生成することです。
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.classSayHelloResponse.class
- Java ソース
- SayHello.javaSayHelloResponse.java
- Contract アーティファクト
- AddressingService.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!"; } }
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>
以下は、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(); } }
5.1. WS-Addressing 1.0 の有効化
- サービスエンドポイントを @Addressing アノテーションでアノテートします。
- JAX-WS Web サービス機能を使用して 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 を設定するためにクライアント実装を更新する必要があります。更新されたクライアントコードは以下のとおりです。
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(); } }
第6章 WS-Reliable Messaging
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
- 将来の再送信のためにアプリケーションメッセージのコピーを作成します。
各インターセプタチェーンに RM インターセプタがあると、必要な場合に RM プロトコルメッセージが交換されます。たとえば、送信インターセプタチェーンの最初のアプリケーションメッセージをインターセプトするときに、RMOutInterceptor
は CreateSequence
要求を送信し、CreateSequenceResponse
応答の受信後に元のアプリケーションメッセージを処理します。また、RM インターセプタはシーケンスヘッダをアプリケーションメッセージに追加し、宛先サイドで、メッセージからシーケンスヘッダを抽出します。
第7章 WS-Reliable Messaging の使用
RM インターセプタは、以下のことが行われた場合にポリシーフレームワークによって各インターセプタチェーンに自動的に追加されます。
- RMAssertion 要素を持つポリシーは
wsdl:service
要素 (または、WS-Policy 添付のルールに従った、Policy または PolicyReference 要素の添付ポイントである他の WSDL 要素) に添付されます。 - CXF WS-Policy フレームワークが有効になります。
<jaxws:endpoint ...> <jaxws:features> <p:policies/> </jaxws:features> </jaxws:endpoint>
<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>
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 の要素 (
AtMostOnce
、AtLeastOnce
、InOrder
)。 - sourcePolicy
- RM ソースの詳細 (オファーを
CreateSequence
要求またはシーケンス終了ポリシーに常に含める必要があるかどうかなど) を設定できるタイプ SourcePolicyType の要素。 - destinationPolicy
- RM 宛先の詳細 (受信オファーを受け入れるかどうかなど) を設定できるタイプ DestinationPolicyType の要素。
- ストア
- 使用するストア (デフォルト値:
null
)。これは、タイプ jdbcStore の要素 (同じネームスペース内)、Bean、または RMStore インターフェースを実装する Bean の参照である必要があります。
<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 チュートリアル
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.classEcho response.classPing.class
- Java ソース
- Echo.javaEchoResponse.javaPing.java
- Contract アーティファクト
- SimpleService.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; } }
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 クライアントアーティファクトの生成
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.classObjectFactory.classPing.classSimpleService_Service.classEchoResponse.classpackage-info.classSimpleService.classSimpleService_SimpleServicePort_Client.class
- Java ソース
- Echo.javaObjectFactory.javaPing.javaSimpleService_Service.javaEchoResponse.javapackage-info.javaSimpleService.javaSimpleService_SimpleServicePort_Client.java
以下は、生成されたアーティファクトを使用した通常の 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 } }
8.3. WS-RM 1.0 の有効化
- WSRM および WS-Addressing ポリシーを含む WS-Policy で WSDL を拡張します。
jbossws-cxf.xml
エンドポイント設定ファイルを提供します。- クライアント CXF 設定を提供します。
- CXF 設定ファイルを読み取るようクライアントコードを更新します。
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>
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.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 への参照。デフォルトセレクタは最小の代替 (つまり、アサーションの数が最小のもの) を選択します。
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.xml
やfile:///x1/resources/polcies.xml
)。
<p:externalAttachment location="classpath:org/apache/cxf/systest/ws/policy/addr-external.xml"/>
<externalAttachment>
要素を指定できます。
第10章 WS-Security
HTTPS
などのトランスポートレベルプロトコルを超えたサービスをセキュアにできます。XML-Encryption や WS-Security 標準で定義されたヘッダなどの標準を介して、以下のことを行えます。
- サービス間で認証トークンを受け渡します。
- メッセージまたはメッセージの一部を暗号化します。
- メッセージを署名します。
- メッセージをタイムスタンプします。
10.1. 暗号化と署名の概要
第11章 JBoss での WSS4J セキュリティ
11.1. Web サービスエンドポイントの作成
- エンドポイント実装を記述し、サービス契約を生成する
wsprovide
JBoss コマンドラインツールを実行します。 wsconsume
JBoss コマンドラインツールを実行してサービス契約からクライアントアーティファクトを取得します (トップダウン方式)。- クライアント実装を記述します。
11.2. WS-Security の有効化
- サービス間で認証トークンを受け渡します。
- メッセージまたはメッセージの一部を暗号化します。
- メッセージを署名します。
- メッセージをタイムスタンプします。
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. パッケージおよびデプロイ
jbossws-cxf.xml
記述子。- プロパティファイル。
- キーストアファイル (署名/暗号化に必要な場合)。
- キーストアパスワードコールバックハンドラクラス。
[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
11.3. 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
記述子で設定する必要があります。
- ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.CALLBACK_HANDLER, new KeystorePasswordCallback());
- ((BindingProvider)proxy).getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES, Thread.currentThread().getContextClassLoader().getResource("META-INF/alice.properties"));
- ((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 サービスユーザーの認証
タスクの概要
ステートレスセション Bean へのセキュアなアクセス
@RolesAllowed
、@PermitAll
、@DenyAll
を用いステートレスセッション Bean にセキュアな状態でアクセス認証済みのユーザーにbean クラスおよびビジネスメソッドのいずれかにおいて上記のアノテーションを用いてロール設定が可能です。@Stateless @RolesAllowed("friend") public class EndpointEJB implements EndpointInterface { ... }
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>
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 セキュリティガイド』を参照してください。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>
セキュリティコンテキストの定義
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認証の有効化 に従ってください。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 { ... }
POJO エンドポイントに対して HTTP の基本的な認証を定義
使用している Web アプリケーションの WEB-INF/web.xml に追加<login-config> <auth-method>BASIC</auth-method> <realm-name>Test Realm</realm-name> </login-config>
クライアントサイド - ユーザー名とパスワードを設定
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");
クライアントサイド - 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認証の有効化
タスクの概要
ステートレスセション Bean へのセキュアなアクセス
@RolesAllowed
、@PermitAll
、@DenyAll
を用いステートレスセッション Bean にセキュアな状態でアクセス認証済みのユーザーにbean クラスおよびビジネスメソッドのいずれかにおいて上記のアノテーションを用いてロール設定が可能です。@Stateless @RolesAllowed("friend") public class EndpointEJB implements EndpointInterface { ... }
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 コンテンツのセキュリティ制限」の項を参照してください。セキュリティドメインの定義
@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 セキュリティガイド』を参照してください。セキュリティコンテキストの定義
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. サンプル
11.5.2. ユーザー名/パスワード設定
passwordCallbackClass
属性を介して jbossws-cxf.xml
(またはプログラムを使用) で設定されます。
11.5.3. 暗号化アルゴリズム
第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
- ネットワークパケットアナライザである Wireshark は SOAP メッセージのルーティングを追跡するのに役に立ちます。非 SOAP エラーメッセージを確認できることにより、これは、CXF クライアントが通常処理できない HTML エラーメッセージをサーバーから取得するときにも役に立ちます。
付録A 改訂履歴
改訂履歴 | |||
---|---|---|---|
改訂 5.1.2-2.400 | 2013-10-31 | Rüdiger Landmann | |
| |||
改訂 5.1.2-2 | 2012-07-18 | Anthony Towns | |
| |||
改訂 5.1.2-100 | Thu 8 December 2011 | Russell Dickenson | |
|