sender-vouches サブジェクト確認方式を使用する自己発行 SAML トークンを作成した後、Java™ API for XML-Based Web Services (JAX-WS) プログラミング・モデルおよび Web Services Security API (WSS API) を使用して、それらのトークンを、トランスポート保護を使用する Web サービス要求メッセージで送信することができます。
始める前に
この作業では、JAX-WS プログラミング・モデル、WSS API インターフェース、SAML の概念、SSL トランスポート保護、および Web サービスの設定を構成および管理するためのポリシー・セットの使用について、ユーザーが十分な知識を持っていることが前提になります。
このタスクについて
Web Services Security プログラミング・インターフェースを使用して sender-vouches サブジェクト確認方式の SAML トークンを SOAP 要求メッセージ内で使用するように、Web サービス・クライアントを作成できます。これらのプログラミング・インターフェースを Web サービス・クライアントで使用して、トランスポート・レベルでのメッセージ保護を使用する sender-vouches サブジェクト確認方式の SAML トークンの使用を指定することは、ポリシー・セットおよびバインディング構成を使用することに代わる方法です。
自己発行 SAML トークンを作成し、その SAML トークンを、Web サービス・クライアントから Web サービス要求メッセージで送信することができます。このタスクで使用される Web サービス・クライアント・アプリケーションは、ダウンロードで使用可能な JaxWSServicesSamples サンプル・アプリケーションに含まれているクライアント・コードの変更版です。
「手順」セクションでサンプルのコード例
について説明し、すぐに使用できる完全な Web サービス・クライアント・サンプル
を「例」セクションに示します。
手順
- Web サービス・プロバイダーを呼び出すために使用する Web サービス・クライアントを特定し、取得します。
このクライアントを使用して、
プログラムで WSS API を使用することによって SAML トークンを SOAP 要求メッセージに
挿入します。
この手順で使用される Web サービス・クライアントは、JaxWSServicesSamples Web サービス・サンプル・アプリケーションに含まれるクライアント・コードの変更版です。
サンプル Web サービス・クライアントを取得して変更し、プログラムで Web Services Security API を使用して SOAP 要求メッセージで SAML sender-vouches トークンを渡すには、以下のステップを実行します。
- JaxWSServicesSamples サンプル・アプリケーションをダウンロードします。 JaxWSServicesSamples サンプルは、デフォルトではインストールされません。
- JaxWSServicesSamples クライアント・コードを取得します。
例を示すため、この手順では、JaxWSServicesSamples サンプルに含まれている Echo シン・クライアント・サンプル
の変更版を使用します。
Web サービス Echo シン・クライアント・サンプル・ファイル SampleClient.java は、src¥SampleClientSei¥src¥com¥ibm¥was¥wssample¥sei¥cli ディレクトリーにあります。
サンプル・クラス・ファイルは、WSSampleClientSei.jar ファイルに含まれています。
JaxWSServicesSamples.ear エンタープライズ・アプリケーションおよびそれをサポートする Java アーカイブ (JAR) ファイルは、JaxWSServicesSamples サンプル・アプリケーション内の installableApps ディレクトリーにあります。
- アプリケーション・サーバーに JaxWSServicesSamples.ear ファイルをデプロイします。 JaxWSServicesSamples.ear ファイルをデプロイしたら、サンプル Web サービス・クライアント・コードを、サンプル・アプリケーションに対してテストする準備ができたことになります。
Web サービス・クライアント・サンプルを使用する代わりに、
ご使用の Web サービス・クライアント・アプリケーションの WSS API を使用して、プログラムで SOAP 要求メッセージの SAML トークンを渡すためにコード・スニペットを追加することもできます。この手順中の例では JAX-WS Web サービス・シン・クライアント
が使用されていますが、管理対象クライアントを使用することもできます。
- SAML20 Bearer WSHTTPS default ポリシー・セット
または SAML11 Bearer WSHTTPS default ポリシー・セットのいずれかのコピーを作成します。
ポリシー・セットのコピーに名前を
付けます。例えば、SAML20 SenderVouches
WSHTTPS または SAML11 SenderVouches WSHTTPS のような名前を付けると、この新しいポリシー・セット
が sender-vouches 確認方式を使用することを識別しやすくなります。
サブジェクト確認方式はポリシー内ではなくバインディング構成に指定されるため、
この新しいポリシー・ファイルには何も変更を加える必要はありません。
この新しいポリシー・ファイル内で、ポリシー ID は SAMLToken20Bearer または SAMLToken11Bearer のいずれかになっています。名前そのものが説明になるように、SAMLToken20Bearer ポリシー ID を SAMLToken20SV に変更するか、
または SAMLToken11Bearer ポリシー ID を SAMLToken11SV に変更して
ください。ポリシーの ID を変更しても、適用されるポリシーの内容は何も変わりませんが、
適切な説明を表す ID を追加すると、これらのポリシー ID が sender-vouches 確認方式を使用することの識別に役立ちます。
これらのポリシーの設定を表示する場合は、
管理コンソールを使用して以下の操作を行います。
- をクリックします。
- 「ポリシー」テーブルで「WS-Security」ポリシーをクリックします。
- 「メイン・ポリシー」リンクまたは「ブートストラップ・ポリシー」リンクをクリックします。
- 「ポリシーの詳細 (Policy Details)」セクションの「要求トークン・ポリシー」をクリック
します。
- この新しい SAML20 SenderVouches WSHTTPS または SAML11 SenderVouches WSHTTPS ポリシー・セットを Web サービス・プロバイダー・アプリケーションに関連付けます。 このポリシー・セットを Web サービス・プロバイダー・アプリケーションに関連付ける方法について詳しくは、『SAML sender-vouches トークン用のクライアントおよびプロバイダーのバインディングの構成』を参照してください。
- SAML Bearer Provider sample default 汎用バインディングのコピーを作成します。
- このデフォルト・ポリシー・セットの新しいコピーに、例えば SAML Sender-vouches provider binding のような、sender-vouches を含む名前を付けます。
- 意図する SAML トークン・バージョン用のトークン・コンシューマー構成内で confirmationMethod プロパティーの
値を sender-vouches に変更します。 保証の要件を満たすように sender-vouches バインディングを変更する
方法について詳しくは、『SAML sender-vouches トークン用のクライアントおよびプロバイダーのバインディングの構成』を
参照してください。
- 新しいプロバイダー・バインディングを JaxWSServicesSamples プロバイダー・サンプルに
割り当てます。 SAML sender-vouches Provider sample, default 汎用バインディングを
Web サービス・プロバイダー・アプリケーションに割り当てる方法について詳しくは、
『SAML sender-vouches トークン用のクライアントおよびプロバイダーのバインディングの構成』を
参照してください。
- Web サービス・プロバイダー SSL 構成属性 clientAuthentication を使用可能にして、X.509 クライアント証明書認証を必要とするようにします。
clientAuthentication 属性は、SSL クライアント認証が必要かどうかを決定します。clientAuthentication 属性を
指定するには、管理コンソールを使用して以下の操作を行います。
- をクリックします。
- 「WC_defaulthost_secure」リンクをクリックします。
- 「関連項目」の下の「SSL_configurations」リンクをクリックします。
- 「NodeDefaultSSLSettings」リソースを選択します。
- 「保護品質 (QoP) 設定」リンクをクリックします。
- メニューから「必要」を選択して、クライアント認証を指定します。
clientAuthentication 属性の構成について詳しくは、
『Secure Sockets Layer 構成の作成』を参照してください。
- Web サービス・クライアント・コード内で CallService() メソッドを使用して、自己発行 SAML トークンの生成に必要な構成パラメーターを含むプロパティー・ファイルを指定します。
CallService() メソッドは、Web Services Security ランタイム環境が自己発行 SAML トークンを生成するために必要な構成パラメーターを指定します。
以下のコード・スニペットは、CallService() メソッドを使用して Web services security 構成パラメーターを指定する方法を示しています。
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* CallService Parms were already read. Now call the service proxy classes
*
*/
void CallService() {
String response = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf ");
// Initialize WSSFactory object
WSSFactory factory = WSSFactory.getInstance();
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
// Initialize SAML issuer configuration via custom properties
HashMap <Object, Object> customProps = new HashMap<Object,Object>();
customProps.put(SamlConstants.ISSUER_URI_PROP, "example.com");
customProps.put(SamlConstants.TTL_PROP, "3600000");
customProps.put(SamlConstants.KS_PATH_PROP, "keystores/saml-provider.jceks");
customProps.put(SamlConstants.KS_TYPE_PROP, "JCEKS");
customProps.put(SamlConstants.KS_PW_PROP, "{xor}LCswLTovPiws");
customProps.put(SamlConstants.KEY_ALIAS_PROP, "samlissuer");
customProps.put(SamlConstants.KEY_NAME_PROP, "CN=SAMLIssuer, O=EXAMPLE");
customProps.put(SamlConstants.KEY_PW_PROP, "{xor}NDomLz4sLA==");
customProps.put(SamlConstants.TS_PATH_PROP, "keystores/saml-provider.jceks");
customProps.put(SamlConstants.TS_TYPE_PROP, "JCEKS");
customProps.put(SamlConstants.TS_PW_PROP, "{xor}LCswLTovPiws");
gencont.add(customProps); //Add custom properties
トークンがどのように構成されるのかを制御する構成プロパティー
の指定方法について詳しくは、『トークン作成中の SAML トークンの構成』を
参照してください。
- Thin Client for JAX-WS JAR ファイルをクラスパスに追加します。 app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar ファイル
をクラスパスに追加します。この JAR ファイルをクラスパスに追加することについて詳しくは、『Web サービス対応クライアントのテスト』を参照してください。
- 自己発行 SAML トークンを作成します。 以下のコード・スニペットは、SAML sender-vouches トークンの作成を示します。
// Create SAMLToken
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
map.put(SamlConstants.SIGNATURE_REQUIRED, "true");
SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);
SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");
System.out.println("SAMLToken id = " + samlToken.getId());
- WSSFactory newSecurityToken メソッドを使用して、
SAML トークンの作成方法を指定します。
SAML トークンを作成するため、以下のメソッドを
指定してください。
WSSFactory newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml")
SAML トークンの作成には、Java セキュリティー
権限 wssapi.SAMLTokenFactory.newSAMLToken が必要です。PolicyTool を
使用して、以下のポリシー・ステートメントを Java セキュリティー・ポリシー・ファイルまたは
アプリケーション・クライアント was.policy ファイルに追加してください。
permission java.security.SecurityPermission "wssapi.SAMLTokenFactory.newSAMLToken
SAMLToken.class パラメーター
は、作成するセキュリティー・トークンのタイプを指定します。
callbackHandler オブジェクト
は、作成する SAMLToken の特性を定義するパラメーターを
含みます。このオブジェクトがポイントする SAMLGenerateCallbackHandler オブジェクト
は、次の表に示す構成パラメーターを指定します。
表 1. SAMLGenerateCallbackHandler プロパティー. この表は、
sender-vouches 確認方式を使用する SAMLGenerateCallbackHandler オブジェクトの
構成パラメーターを示します。プロパティー |
説明 |
必須 |
SamlConstants.CONFIRMATION_METHOD |
sender-vouches 確認方式の使用を指定します。 |
はい |
SamlConstants.TOKEN_TYPE |
定数値 WSSConstants.SAML.SAML20_VALUE_TYPE を
使用して、SAML 2.0 トークン・タイプを指定します。
Web サービス・クライアントにポリシー・セットが関連付けられている場合、Web Services Security ランタイム環境はこのプロパティーを使用しません。このシナリオの場合は、tokenGenerator バインディング構成
の valueType 属性でトークン・タイプの値を指定します。
この手順中の例では SAML 2.0 トークン
が使用されていますが、WSSConstants.SAML.SAML11_VALUE_TYPE 値を使用することもできます。
|
はい |
SamlConstants.SAML_NAME_IDENTIFIER |
SAMLToken 内の NameID 値として
ユーザー ID (例えば、myname) を指定します。
Thin Client for JAX-WS を
使用しているときにこのパラメーターを定義しないと、NameID 値に有効な情報が含まれません。
Web サービス要求呼び出しを作成する Java Platform, Enterprise Edition (Java EE) アプリケーションなどの Web サービス管理対象クライアントを使用している場合、Web Services Security ランタイム環境は、ユーザー・セキュリティー情報をセキュリティー・コンテキストから抽出しようとします。同じように、管理対象 Web サービス・クライアントに対してこのパラメーターを定義しない場合、NameID 値は、UNAUTHENTICATED 名前 ID を含みます。
Web サービス・クライアントにポリシー・セットが関連付けられている場合は、このプロパティーは使用されません。SAML トークンの ID および属性の送信について詳しくは、SAML トークンの送信に関するセクションを参照してください。
|
いいえ |
SamlConstants.SIGNATURE_REQUIRED |
発行者が SAML トークンにデジタルに署名する
必要があるかどうかを指定します。
true 値
は、発行者が SAML トークンにデジタルに署名する必要があることを指定します。
この値がデフォルトです。
|
いいえ |
system.wss.generate.saml パラメーターは、SAML トークンの作成に使用される Java Authentication
and Authorization Service (JAAS) ログイン・モジュールを指定します。次の例のように、必要な JAAS ログイン構成を含んでいる JAAS 構成ファイルを定義するため、JVM プロパティー
を指定する必要があります。
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
あるいは、次の例のように、
サンプル・クライアント・コード内で Java システム・プロパティー
を設定することによって、JAAS ログイン構成ファイルを指定できます。
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf ");
- 作成された SAML トークンのトークン ID を取得します。
以下のステートメントを、作成した SAML トークンの簡単なテストとして使用できます。
System.out.println("SAMLToken id = " + samlToken.getId())
タスクの結果
トランスポート保護とともに sender-vouches 確認方式を使用する自己発行 SAML トークンを作成してから、JAX-WS プログラミング・モデルおよび WSS API を使用して、Web サービス要求メッセージでそのトークンを送信しました。
例
以下のコード例は、自己発行 SAML sender-vouches トークンを作成し、
その SAML トークンを Web サービス要求メッセージに入れて送信する方法を示す、
すぐに使用できる完全な Web サービス・クライアント・アプリケーションです。このサンプル・コードは、上記の手順を
示しています。
/**
* The following source code is sample code created by IBM Corporation.
* This sample code is provided to you solely for the purpose of assisting you in the
* use of the technology. The code is provided 'AS IS', without warranty or condition of
* any kind. IBM shall not be liable for any damages arising out of your use of the
* sample code, even if IBM has been advised of the possibility of such damages.
*/
package com.ibm.was.wssample.sei.cli;
import com.ibm.was.wssample.sei.echo.EchoService12PortProxy;
import com.ibm.was.wssample.sei.echo.EchoStringInput;
import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;
import java.util.Map;
import java.util.HashMap;
import javax.xml.ws.BindingProvider;
public class SampleSamlSVClient {
private String urlHost = "localhost";
private String urlPort = "9081";
private static final String CONTEXT_BASE = "/WSSampleSei/";
private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
private String message = "HELLO";
private String uriString = "http://" + urlHost + ":" + urlPort;
private String endpointURL = uriString + ECHO_CONTEXT12;
private String input = message;
/**
* main()
*
* see printusage() for command-line arguments
*
* @param args
*/
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* CallService Parms were already read. Now call the service proxy classes.
*
*/
void CallService() {
String response = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config", "profile_root/properties/wsjaas_client.conf ");
// Initialize WSSFactory object
WSSFactory factory = WSSFactory.getInstance();
// Initialize WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
// Initialize SAML issuer configuration via custom properties
HashMap<Object, Object> customProps = new HashMap<Object,Object>();
customProps.put(SamlConstants.ISSUER_URI_PROP, "example.com");
customProps.put(SamlConstants.TTL_PROP, "3600000");
customProps.put(SamlConstants.KS_PATH_PROP, "keystores/saml-provider.jceks");
customProps.put(SamlConstants.KS_TYPE_PROP, "JCEKS");
customProps.put(SamlConstants.KS_PW_PROP, "{xor}LCswLTovPiws");
customProps.put(SamlConstants.KEY_ALIAS_PROP, "samlissuer");
customProps.put(SamlConstants.KEY_NAME_PROP, "CN=SAMLIssuer, O=EXAMPLE");
customProps.put(SamlConstants.KEY_PW_PROP, "{xor}NDomLz4sLA==");
customProps.put(SamlConstants.TS_PATH_PROP, "keystores/saml-provider.jceks");
customProps.put(SamlConstants.TS_TYPE_PROP, "JCEKS");
customProps.put(SamlConstants.TS_PW_PROP, "{xor}LCswLTovPiws");
gencont.add(customProps); //Add custom properties
// Create SAMLToken
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(SamlConstants.CONFIRMATION_METHOD, "sender-vouches");
map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
map.put(SamlConstants.SIGNATURE_REQUIRED, "true");
SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);
SecurityToken samlToken = factory.newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml");
System.out.println("SAMLToken id = " + samlToken.getId());
// Initialize web services client
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configure SOAPAction properties
BindingProvider bp = (BindingProvider) (echo._getDescriptor().getProxy());
Map<String, Object> requestContext = bp.getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);
requestContext.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
requestContext.put(BindingProvider.SOAPACTION_URI_PROPERTY, "echoOperation");
gencont.add(samlToken);
// Add timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
gencont.process(requestContext);
// Build the input object
EchoStringInput echoParm =
new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
echoParm.setEchoInput(input);
System.out.println(">> CLIENT: SEI Echo to " + endpointURL);
// Prepare to consume timestamp in response message
WSSConsumingContext concont = factory.newWSSConsumingContext();
concont.add(WSSConsumingContext.TIMESTAMP);
concont.process(requestContext);
// Call the service
response = echo.echoOperation(echoParm).getEchoResponse();
System.out.println(">> CLIENT: SEI Echo invocation complete.");
System.out.println(">> CLIENT: SEI Echo response is: " + response);
} catch (Exception e) {
System.out.println(">> CLIENT: ERROR: SEI Echo EXCEPTION.");
e.printStackTrace();
}
}
}
この Web サービス・クライアント・アプリケーション・サンプルが正しく実行された場合、次のようなメッセージを受け取ります。
SAMLToken id = _6CDDF0DBF91C044D211271166233407
Retrieving document at 'file:profile_root/.../wsdl/'.
>> CLIENT: SEI Echo to http://localhost:9443/WSSampleSei/EchoService12
>> CLIENT: SEI Echo invocation complete.
>> CLIENT: SEI Echo response is: SOAP12==>>HELLO