Sie können selbst ausgestellte SAML-Token mit der Subjektbestätigungsmethode "Holder-of-Key" erstellen und dann das
Programmiermodel JAX-WS (Java™ API for XML-Based Web Services) und WSS-APIs (Web Services Security APIs)
nutzen, um diese
Token über Web-Service-Anforderungsnachrichten zu senden.
Vorbereitende Schritte
Für diese Task müssen Sie mit dem Programmiermodell JAX-WS, den WSS-APIs, mit SAML-Konzepten
sowie mit Richtliniensätzen zum Konfigurieren und Verwalten von Web-Service-Einstellungen vertraut sein. Gehen Sie
wie folgt vor, bevor Sie mit dieser Task beginnen:
- Lesen Sie die Informationen zum Senden von selbst ausgestellten SAML-Bearer-Token über WSS-APIs.
- Lesen Sie die Informationen zum Senden von selbst ausgestellten SAML-Sender-Vouches-Token über WSS-APIs mit Nachrichtenschutz.
Informationen zu diesem Vorgang
Diese Task konzentriert sich auf die Verwendung des symmetrischen Schlüssels, der von
SAML-Sicherheitstoken für die Generierung einer digitalen Signatur für ausgewählte SOAP-Nachrichtenelemente angegeben wird,
um Sicherheitsanforderungen der Subjektbestätigungsmethode "Holder-of-Key" zu erfüllen. Die WS-Security-Richtlinie, die dem Web-Service-Provider
zugeordnet ist, stammt aus dem Richtliniensatz
SAML20 HoK Symmetric WSSecurity default, der mit
WebSphere Application Server 7.0.0.7 und späteren Releases bereitgestellt wird.
Vorgehensweise
- Erstellen Sie ein SAML-Sicherheitstoken, das die Subjektbestätigungsmethode "Holder-of-Key" enthält. Beispiel:
WSSFactory factory = WSSFactory.getInstance();
// WSSGenerationContext initialisieren
com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext gencont = factory.newWSSGenerationContext();
// Konfiguration des SAML-Ausstellers über angepasste Eigenschaften initialisieren
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); // Angepasste Eigenschaften hinzufügen
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.SERVICE_ALIAS, "soaprecipient");
map.put(SamlConstants.KEY_TYPE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey");
map.put(SamlConstants.SAML_APPLIES_TO, "http://localhost:9080/your_Web_service");
map.put(RequesterConfiguration.RSTT.ENCRYPTIONALGORITHM,
"http://www.w3.org/2001/04/xmlenc#aes256-cbc");
map.put(SamlConstants.KEY_SIZE, "256");
SAMLGenerateCallbackHandler callbackHandler = new SAMLGenerateCallbackHandler(map);
SAMLToken samlToken = (SAMLToken) factory.newSecurityToken(SAMLToken.class,
callbackHandler, "system.wss.generate.saml");
Der im SAML-Sicherheitstoken eingebettete Nachweisschlüssel wird für den Ziel-Web-Service verschlüsselt. Der
öffentliche Schlüssel des Zielservice verschlüsselt den mit der Eigenschaft SamlConstants.SERVICE_ALIAS definierten
Nachweisschlüssel. Die Eigenschaft gibt ein öffentliches Zertifikat in der Trust-Datei an. Die Position der Trust-Datei
wird von der angepassten Eigenschaft com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext festgelegt. In diesem Beispiel verwendet die Verschlüsselung eine Schlüsselgröße von 256 Bit,
Sie müssen also die JCE-Richtliniendatei Java Cryptography Extension) importieren. Weitere Informationen hierzu finden Sie
im Abschnitt "Nicht eingeschränkte JCE-Richtliniendateien verwenden" im Artikel
"Web-Services-Security-Anwendungen optimieren".
Wenn Sie, anstatt symmetrische Schlüssel direkt zu verwenden,
lieber abgeleitete Schlüssel für digitale Signaturen und Verschlüsselung verwenden möchten, müssen Sie das folgende Name/Wert-Paar hinzufügen:
map.put(SamlConstants.REQUIRE_DKT, "true");
- Verwenden Sie das Objekt WSSGenerationContext, um die Verarbeitung des Sicherheitsheaders der Anforderungsnachricht vorzubereiten.
Beispiel:
gencon.add(samlToken); // diese Codezeile kann übergangen werden
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencon.add(timestamp);
WSSSignature sig = factory.newWSSSignature(samlToken);
sig.setSignatureMethod(WSSSignature.HMAC_SHA1);
sig.setCanonicalizationMethod(WSSSignature.EXC_C14N);
sig.addSignPart(WSSSignature.BODY);
sig.addSignPart(WSSSignature.TIMESTAMP);
sig.addSignPart(WSSSignature.ADDRESSING_HEADERS);
sig.setTokenReference(SecurityToken.REF_KEYID);
// Wenn die Codezeile "gencon.add(samlToken);" übergangen oder "DerivedKey" verwendet wird,
// muss die obige Codezeile durch
// "sig.setTokenReference(SecurityToken.REF_STR);" ersetzt werden.
gencon.add(sig);
WSSEncryption enc = factory.newWSSEncryption(samlToken);
enc.setEncryptionMethod(WSSEncryption.AES256);
enc.setTokenReference(SecurityToken.REF_KEYID);
// Wenn die Codezeile "gencon.add(samlToken);" übergangen oder "DerivedKey" verwendet wird,
// muss die obige Codezeile durch
// "enc.setTokenReference(SecurityToken.REF_STR);" ersetzt werden.
enc.encryptKey(false);
enc.addEncryptPart(WSSEncryption.BODY_CONTENT);
enc.addEncryptPart(WSSEncryption.SIGNATURE);
gencon.add(enc);
- Erstellen Sie das Objekt WSSConsumingContext, um die Verarbeitung des Sicherheitsheaders der Antwortnachricht vorzubereiten.
Beispiel:
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.encryptKey(false);
dec.addRequiredDecryptPart(WSSDecryption.BODY_CONTENT);
concont.add(dec);
callbackHandler = new SAMLConsumerCallbackHandler(map);
WSSVerification ver = factory.newWSSVerification(SAMLToken.class, callbackHandler,
"system.wss.consume.saml");
ver.addAllowedSignatureMethod(WSSVerification.HMAC_SHA1);
ver.addRequiredVerifyPart(WSSVerification.BODY);
ver.addRequiredVerifyPart(WSSVerification.TIMESTAMP);
concont.add(ver);
- Verwenden Sie das JDK-Dienstprogramm keytool, um die Dateien
saml-provider.jceks und recipient.jceks, die zum Testen des Beispielcodes verwendet werden, zu generieren.
Beispiel:
keytool -genkey -alias samlissuer -keystore saml-provider.jceks -dname "CN=SAMLIssuer, O=ACME" -storepass issuerstorepass
-keypass issuerkeypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -genkey -alias soaprecipient -keystore recipient.jceks -dname "CN=SOAPRecipient, O=ACME" -storepass reciptstorepass -keypass reciptkeypass -storetype jceks -validity 5000 -keyalg RSA -keysize 2048
keytool -export -alias soaprecipient -file reciptpub.cer -keystore recipient.jceks -storepass reciptstorepass -storetype jceks
keytool -import -alias soaprecipient -file reciptpub.cer -keystore saml-provider.jceks -storepass issuerstorepass -storetype jceks -keypass issuerkeypass -noprompt
Ergebnisse
Sie haben sich mit wichtigen Bausteinen vertraut gemacht, die Sie benötigen, um
eine Web-Service-Clientanwendung zu erstellen mit dem Ziel, ein SAML-Sicherheitstoken in einer SOAP-Nachricht zu senden.
Außerdem haben Sie gelernt, wie Sie den in der SAML-Sicherheitseinrichtung eingebetteten symmetrischen Schlüssel
verwenden, um Nachrichtenschutz zu gewährleisten.