holder-of-key サブジェクト確認メソッドを含む自己発行 SAML トークンを作成し、
Java™ API for XML-Based Web Services (JAX-WS) プログラミング・モデルおよび Web Services Security API (WSS API) を使用して、Web サービス要求メッセージによりこれらのトークンを送信することができます。
始める前に
この作業では、JAX-WS プログラミング・モデル、WSS API インターフェース、SAML の概念、および Web サービスの設定を構成および管理するためのポリシー・セットの使用について、ユーザーが十分な知識を持っていることが前提になります。このタスクを開始する前に、以下のアクションを実行します。
- WSS API を使用した自己発行 SAML bearer トークンの送信についての資料を参照してください。
- メッセージ・レベル保護とともに WSS API を使用した自己発行 SAML sender-vouches トークンの送信についての資料を参照してください。
このタスクについて
このタスクは、holder-of-key サブジェクト確認方式セキュリティー要件を満たすために、SAML セキュリティー・トークンによって識別される非対称鍵を使用して、選択された SOAP メッセージ・エレメントのデジタル署名を生成することに焦点を当てたものです。
送信側の X.509 certificate が SAML セキュリティー・トークン中に埋め込まれます。
送信側は、対応する秘密鍵を使用することによって要求メッセージ・エレメントの選択された部分に署名し、受信側の公開鍵を使用することによって要求メッセージを暗号化します。
受信側は、受信側の秘密鍵を使用することによって応答メッセージの選択されたエレメントに署名し、SAML セキュリティー・トークン内で送信側の公開鍵を使用することによって応答メッセージの選択されたエレメントを暗号化します。
Web サービス・プロバイダーに付加された Web Services Security ポリシーは、参照用に提供されているものです。
手順
- holder-of-key サブジェクト確認方式を含む SAML セキュリティー・トークンを作成します。例:
WSSFactory factory = WSSFactory.getInstance();
// Initialize WSSGenerationContext
com.ibm.websphere.wssecurity.wssapi.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
HashMap<Object, Object> map = new HashMap<Object, Object>();
map.put(SamlConstants.CONFIRMATION_METHOD, "holder-of-key");
map.put(SamlConstants.Token_REQUEST, "issue");
map.put(SamlConstants.TOKEN_TYPE, WSSConstants.SAML.SAML20_VALUE_TYPE);
map.put(SamlConstants.SAML_NAME_IDENTIFIER, "Alice");
map.put(SamlConstants.SIGNATURE_REQUIRED, "true");
map.put(SamlConstants.KEY_TYPE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey");
map.put(SamlConstants.SAML_APPLIES_TO, "http://localhost:9080/your_Web_service");
map.put(SamlConstants.KEY_ALIAS, "soapinitiator" );
map.put(SamlConstants.KEY_NAME, "CN=SOAPInitator, O=ACME");
map.put(SamlConstants.KEY_PASSWORD, "keypass");
map.put(SamlConstants.KEY_STORE_PATH, "keystores/initiator.jceks");
map.put(SamlConstants.KEY_STORE_PASSWORD, "storepass");
map.put(SamlConstants.KEY_STORE_TYPE, "jceks");
SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);
SAMLToken samlToken = (SAMLToken) factory.newSecurityToken(SAMLToken.class,
callbackHandler, "system.wss.generate.saml");
送信側の秘密鍵は SamlConstants.KEY_ALIAS プロパティーによって指定され、要求メッセージの選択されたエレメントに署名するために使用されます。
- WSSGenerationContext オブジェクトを使用することによって、要求メッセージのセキュリティー・ヘッダーの処理のための準備をします。例:
gencon.add(samlToken); //this line of code can be omitted
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencon.add(timestamp);
WSSSignature sig = factory.newWSSSignature(samlToken);
sig.setTokenReference(SecurityToken.REF_KEYID);
//If the gencon.add(samlToken); line of code is omitted,
//the above line of code must be replaced with
//sig.setTokenReference(SecurityToken.REF_STR);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
sig.setCanonicalizationMethod(WSSSignature.EXC_C14N);
sig.addSignPart(WSSSignature.BODY);
sig.addSignPart(WSSSignature.TIMESTAMP);
sig.addSignPart(WSSSignature.ADDRESSING_HEADERS);
gencon.add(sig);
X509GenerateCallbackHandler x509callbackHandler2 = new X509GenerateCallbackHandler(
null,
"keystores/initiator.jceks",
"jceks",
"storepass".toCharArray(),
"soaprecipient",
null,
"", null);
SecurityToken st2 = factory.newSecurityToken(X509Token.class, x509callbackHandler2);
WSSEncryption enc = factory.newWSSEncryption(st2);
enc.addEncryptPart(WSSEncryption.BODY_CONTENT);
enc.addEncryptPart(WSSEncryption.SIGNATURE);
enc.setEncryptionMethod(WSSEncryption.AES256);
enc.setKeyEncryptionMethod(WSSEncryption.KW_RSA_OAEP);
gencon.add(enc);
この例の場合、暗号化で鍵サイズとして 256 ビットが使用されているため、Java Cryptography Extension (JCE) のポリシー・ファイルをインポートする必要があります。
詳しくは、『Web Services Security アプリケーションの調整』のトピックで、無制限 JCE ポリシー・ファイルの使用に関する説明を参照してください。
- 応答メッセージのセキュリティー・ヘッダーの処理の準備のため、WSSConsumingContext オブジェクトを作成します。例:
WSSConsumingContext concont = factory.newWSSConsumingContext();
HashMap<Object, Object> map = new HashMap<Object, Object>();
SAMLConsumerCallbackHandler callbackHandler = new SAMLConsumerCallbackHandler(map);
WSSDecryption dec = factory.newWSSDecryption(SAMLToken.class, callbackHandler,
"system.wss.consume.saml");
dec.addAllowedEncryptionMethod(WSSDecryption.AES256);
dec.addAllowedKeyEncryptionMethod(WSSDecryption.KW_RSA_OAEP);
dec.encryptKey(false);
dec.addRequiredDecryptPart(WSSDecryption.BODY_CONTENT);
concont.add(dec);
X509ConsumeCallbackHandler verHandler = new X509ConsumeCallbackHandler(null,
"keystores/initiator.jceks",
"jceks",
"storepass".toCharArray(),
"soaprecipient",
null, null);
WSSVerification ver = factory.newWSSVerification(X509Token.class, verHandler);
ver.addRequiredVerifyPart(WSSVerification.BODY);
concont.add(ver);
- JDK keytool ユーティリティーを使用することにより、サンプル・コードのテストに使用する saml-provider.jceks、initiator.jceks、および recipient.jceks の各ファイルを生成します。例:
keytool -genkey -alias samlissuer -keystore saml-provider.jceks -dname "CN=SAMLIssuer, O=ACME" -storepass myissuerstorepass -keypass myissuerkeypass
-storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -genkey -alias soaprecipient -keystore recipient.jceks -dname "CN=SOAPRecipient, O=ACME" -storepass myreciptstorepass -keypass myreciptkeypass
-storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -genkey -alias soapinitiator -keystore initiator.jceks -dname "CN=SOAPInitator, O=ACME" -storepass myinitatstorepass -keypass myinitatkeypass
-storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -export -alias samlissuer -file issuerpub.cer -keystore saml-provider.jceks -storepass myissuerstorepass -storetype jceks
keytool -export -alias soaprecipient -file reciptpub.cer -keystore recipient.jceks -storepass myreciptstorepass -storetype jceks
keytool -export -alias soapinitiator -file initatpub.cer -keystore initiator.jceks -storepass myinitatstorepass -storetype jceks
keytool -import -alias samlissuer -file issuerpub.cer -keystore initiator.jceks -storepass myissuerstorepass -storetype jceks -keypass myissuerkeypass -noprompt
keytool -import -alias soaprecipient -file reciptpub.cer -keystore initiator.jceks -storepass myreciptstorepass -storetype jceks -keypass myreciptkeypass -noprompt
keytool -import -alias samlissuer -file issuerpub.cer -keystore recipient.jceks -storepass myreciptstorepass -storetype jceks -keypass myreciptkeypass -noprompt
keytool -import -alias soapinitiator -file initatpub.cer -keystore initiator.jceks -storepass myinitatstorepass -storetype jceks -keypass myinitatkeypass -noprompt
keytool -import -alias soapinitiator -file initatpub.cer -keystore saml-provider.jceks -storepass myissuerstorepass -storetype jceks -keypass myissuerkeypass -noprompt
タスクの結果
これで、Web サービス・クライアント・アプリケーション作成のための主なビルディング・ブロックについて学習しました。
それは、SOAP メッセージの中で SAML セキュリティー・トークンを送信し、メッセージ・レベル保護で SAML セキュリティーに埋め込まれる非対称鍵を使用することを目的としたものでした。
例
以下は、Web サービス・プロバイダーの Web Services Security ポリシーの例です。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:spe="http://www.ibm.com/xmlns/prod/websphere/200605/ws-securitypolicy-ext">
<wsp:Policy wsu:Id="response:app_encparts">
<sp:EncryptedElements>
<sp:XPath>/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Envelope']/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']</sp:XPath>
<sp:XPath>/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Envelope']/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']</sp:XPath>
</sp:EncryptedElements>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:Policy>
<wsp:Policy wsu:Id="request:req_enc">
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:Policy>
<wsp:Policy wsu:Id="request:app_signparts">
<sp:SignedParts>
<sp:Body/>
<sp:Header Namespace="http://schemas.xmlsoap.org/ws/2004/08/addressing"/>
<sp:Header Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:SignedElements>
<sp:XPath>/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Envelope']/*[namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
and local-name()='Timestamp']</sp:XPath>
<sp:XPath>/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Envelope']/*[namespace-uri()='http://www.w3.org/2003/05/soap-envelope'
and local-name()='Header']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'
and local-name()='Security']/*[namespace-uri()='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'
and local-name()='Timestamp']</sp:XPath>
</sp:SignedElements>
</wsp:Policy>
<wsp:Policy wsu:Id="response:resp_sig">
<sp:SignedParts>
<sp:Body/>
</sp:SignedParts>
</wsp:Policy>
<sp:AsymmetricBinding>
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<spe:CustomToken sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/Always"/>
<wsp:Policy>
<spe:WssCustomToken localname="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"/>
</wsp:Policy>
</spe:CustomToken>
</wsp:Policy>
</sp:InitiatorToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:IncludeTimestamp/>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200512/IncludeToken/Always"/>
<wsp:Policy>
<sp:WssX509V3Token11/>
</wsp:Policy>
</sp:X509Token>
<wsp:Policy>
<sp:RecipientToken>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<wsp:Policy>
<sp:AsymmetricBinding>
</wsp:Policy>