Sie können selbst ausgestellte SAML-Token mit der Subjektbestätigungsmethode Sender-Vouches 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 mit Nachrichtenschutz 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.
Informationen zu diesem Vorgang
Sie können SOAP-Anforderungsnachrichten und
SAML-Token mithilfe der WSS-Programmierschnittstelle (Web Services
Security) schützen, um den Validierungsanforderungen der Subjektbestätigungsmethode Sender-Vouches mit Nachrichtenschutz
gerecht zu werden.
Die Verwendung der Programmierschnittstellen im Web-Service-Client ist eine alternative Herangehensweise zur
Nutzung eines Richtliniensatzes und einer Bindungskonfiguration.
Sie können ein selbst ausgestelltes
SAML-Token erstellen und dieses dann in Web-Service-Anforderungsnachrichten von einem Web-Service-Client aus
senden. Der für diese Task verwendete Web-Service-Anwendungsclient ist eine modifizierte Version des
Clientcodes in der Beispielanwendung JaxWSServicesSamples, die zum Download verfügbar ist. Im Prozedurenabschnitt sind Codefragmente des Beispiels beschrieben. Im Abschnitt "Beispiel" finden Sie
einen vollständigen, sofort einsatzfähigen Beispiel-Web-Service-Client.
Mit diesem Produkt wird kein Standardrichtliniensatz bereitgestellt, der
SAML-Token mit der Subjektbestätigungsmethode Sender-Vouches erfordert. Lesen Sie hier, wie die Client- und Providerbindungen für das
SAML-Sender-Vouches-Token konfiguriert werden, und informieren Sie sich darüber, wie eine Web-Services-Security-Richtlinie erstellt wird, die
SAML-Token mit der Subjektbestätigungsmethode Sender-Vouches erfordert, und wie eine angepasste Bindungskonfiguration erstellt wird. Die Richtlinie und die Bindung
müssen Sie dem Web-Service-Provider zuordnen. Das in dieser Task beschriebene Codebeispiel setzt voraus, dass die Web-Service-Providerrichtlinie erfordert, dass
die SAML-Token und die Hauptteile der Nachrichten digital mit einem
X.509-Sicherheitstoken signiert sind.
Vorgehensweise
- Ermitteln Sie den Web-Service-Client, mit dem Sie einen Web-Service-Provider aufrufen möchten, und fordern Sie diesen Client an.
Fügen Sie mit diesem Client über WSS-APIs
programmgestützt SAML-Token in SOAP-Anforderungsnachrichten ein.
Der in dieser Prozedur verwendete Web-Service-Client ist eine modifizierte Version des
Clientcodes, der in der Web-Service-Beispielanwendung JaxWSServicesSamples enthalten ist.
Führen Sie die folgenden Schritte aus, um den Beispiel-Web-Service-Client anzufordern und über WSS-APIs zu modifizieren, um
SAML-Sender-Vouches-Token programmgesteuert in SOAP-Anforderungsnachrichten übergeben zu können:
- Laden Sie die Beispielanwendung JaxWSServicesSamples herunter. Das Beispiel JaxWSServicesSamples ist standardmäßig nicht installiert.
- Fordern Sie den Clientcode für JaxWSServicesSamples an.
Zu Demonstrationszwecken verwendet diese Prozedur eine modifizierte Version des
Thin-Client-Beispiels Echo, das
Teil des Beispiels JaxWSServicesSamples ist.
Die Datei SampleClient.java des Web Services Thin Client "Echo"
befindet sich im Verzeichnis src\SampleClientSei\src\com\ibm\was\wssample\sei\cli.
Die Beispielklassendatei ist in der Datei WSSampleClientSei.jar enthalten.
Die Unternehmensanwendung
JaxWSServicesSamples.ear und die unterstützenden JAR-Dateien (Java-Archiv)
befinden sich im Verzeichnis installableApps in der Beispielanwendung
"JaxWSServicesSamples".
- Implementieren Sie die Datei JaxWSServicesSamples.ear auf dem Anwendungsserver. Nachdem Sie die Datei JaxWSServicesSamples.ear implementiert haben, können Sie den Code des Beispiel-Web-Service-Clients
anhand der Beispielanwendung testen.
Anstatt den Beispiel-Web-Service-Client zu verwenden, können Sie auch die Codefragmente hinzufügen, um in Ihrer eigenen Web-Service-Clientanwendung
SAML-Token über WSS-APIs programmgestützt in SOAP-Anforderungsnachrichten zu übergeben. Das Beispiel in dieser Prozedur nutzt einen Web Services Thin Client für JAX-WS.
Sie können aber auch einen verwalteten Client verwenden.
- Geben Sie mit der Methode CallService() die Konfigurationsparameter für Web Services Security an, die für das Aufrufen eines
Ziel-Web-Service-Providers mit einem selbst ausgestellten SAML-Token erforderlich sind.
Die Methode CallService() gibt die Konfigurationsparameter an, die die WS-Security-Laufzeitumgebung benötigt,
um ein selbst ausgestelltes SAML-Token über die angepasste Eigenschaft com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext zu generieren.
Das folgende Codefragment veranschaulicht die Verwendung der Methode
CallService() zum Setzen der Systemeigenschaft
SamlConstants.SAML_SELF_ISSUER_CONFIG.
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* CallService-Parameter wurden gelesen. Jetzt können die Serviceproxyklassen aufgerufen werden.
*
*/
void CallService() {
String response = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config", "Profilstammverzeichnis/properties/wsjaas.conf");
Lesen Sie hier, wie ein SAML-Token bei seiner Erstellung konfiguriert wird, und erfahren Sie,
wie Sie Konfigurationseigenschaften angeben können, um zu steuern, wie das Token konfiguriert wird.
- Fügen Sie die JAR-Datei des Thin Client für JAX-WS zum Klassenpfad hinzu. Fügen Sie die Datei Stammverzeichnis_des_Anwendungsservers/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar zum Klassenpfad hinzu. Lesen Sie die Informationen zum Testen von Clients mit Unterstützung für Web Services, um zu erfahren, wie diese JAR-Datei
zum Klassenpfad hinzugefügt wird.
- Erstellen Sie das selbst ausgestellte SAML-Token. Das folgende Codefragment veranschaulicht die Erstellung des SAML-Tokens:
// SAML-Token erstellen
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());
- Geben Sie mit der Methode WSSFactory newSecurityToken an, wie das SAML-Token erstellt werden soll.
Geben Sie folgende Methode an, um das SAML-Token zu erstellen:
WSSFactory newSecurityToken(SAMLToken.class, callbackHandler, "system.wss.generate.saml")
Die Erstellung eines
SAML-Tokens erfordert die Java-Sicherheitsberechtigung
wssapi.SAMLTokenFactory.newSAMLToken. Fügen Sie zur Datei mit der
Java-Sicherheitsrichtlinie oder der Datei
was.policy des Anwendungsclients die folgende Richtlinienanweisung hinzu:
permission java.security.SecurityPermission "wssapi.SAMLTokenFactory.newSAMLToken
Der Parameter SAMLToken.class gibt den Typ des zu erstellenden Sicherheitstokens
an.
Das Objekt
callbackHandler enthält Parameter, die die Merkmale des zu erstellenden
SAML-Tokens definieren. Dieses Objekt zeigt auf ein Objekt SAMLGenerateCallbackHandler,
das die in der folgenden Tabelle beschriebenen Konfigurationsparameter angibt:
Tabelle 1. Eigenschaften von SAMLGenerateCallbackHandler. In der folgenden Tabelle sind die Konfigurationsparameter für das Objekt SAMLGenerateCallbackHandler
bei Verwendung der Bestätigungsmethode Sender-Vouches beschrieben. Eigenschaft |
Beschreibung |
Erforderlich |
SamlConstants.CONFIRMATION_METHOD |
Gibt an, dass die Bestätigungsmethode sender-vouches verwendet werden soll |
Ja |
SamlConstants.TOKEN_TYPE |
Gibt mit dem Konstantenwert WSSConstants.SAML.SAML20_VALUE_TYPE einen
SAML-2.0-Tokentyp an.
Wenn einem Web-Service-Client Richtliniensätze zugeordnet sind, wird diese Eigenschaft nicht von der Web-Services-Security-Laufzeit verwendet. Geben Sie in diesem Szenario
den Tokenwerttyp mit dem Attribut valueType der tokenGenerator-Bindungskonfiguration an.
Das Beispiel in dieser Prozedur nutzt ein SAML-2.0-Token.
Sie können aber auch den Wert WSSConstants.SAML.SAML11_VALUE_TYPE verwenden.
|
Ja |
SamlConstants.SAML_NAME_IDENTIFIER |
Gibt eine Benutzeridentität wie
myname als NameID-Wert des SAML-Tokens an
Wenn Sie den Thin Client für JAX-WS verwenden und diesen Parameter nicht definieren,
enthält der
NameID-Wert keine sinnvollen Informationen.
Wenn Sie einen
verwalteten Web-Service-Client verwenden, z. B. eine Java-EE-Anwendung, die eine Web-Service-Anforderung aufruft,
versucht die Web-Services-Security-Laufzeitumgebung, Informationen zur Benutzersicherheit aus dem Sicherheitskontext zu extrahieren. Wenn Sie einen verwalteten Web-Service-Client verwenden und diesen Parameter
nicht definieren, enthält der
NameID-Wert den Namen UNAUTHENTICATED.
Diese Eigenschaft wird nicht verwendet, wenn Ihrem Web-Service-Client Richtliniensätze zugeordnet sind. Lesen Sie hier, wie SAML-Token gesendet werden,
und erfahren Sie, wie ID und Attribute eines SAML-Tokens gesendet werden.
|
Nein |
SamlConstants.SIGNATURE_REQUIRED |
Gibt an, ob der Aussteller das SAML-Token digital signieren muss
Der Wert true gibt an, dass
der Aussteller das SAML-Token digital signieren muss.
Dieser
Wert ist der Standardwert.
|
Nein |
Der Parameter
system.wss.generate.saml gibt an, dass eine JAAS-Anmeldekonfiguration
verwendet werden soll und welches Anmeldemodul für die Erstellung
des SAML-Tokens aufgerufen werden soll. Sie müssen eine
JVM-Eigenschaft angeben, um eine JAAS-Konfigurationsdatei mit der erforderlichen
JAAS-Anmeldekonfiguration zu definieren. Beispiel:
Djava.security.auth.login.config=Profilstammverzeichnis/properties/wsjaas.conf
Alternativ können Sie mit einer
Java-Systemeigenschaft im Beispielclientcode eine JAAS-Anmeldekonfigurationsdatei angeben,
z. B.
System.setProperty("java.security.auth.login.config", "Profilstammverzeichnis/properties/wsjaas.conf");
- Fordern Sie die Token-ID des erstellten SAML-Tokens an.
Verwenden Sie als einfachen Test für das von Ihnen erstellte SAML-Token
die folgende Anweisung:
System.out.println("SAMLToken id = " + samlToken.getId())
- Fügen Sie das SAML-Token zum SOAP-Sicherheitsheader von Web-Service-Anforderungsnachrichten hinzu.
- Initialisieren Sie den Web-Service-Client und konfigurieren Sie die
SOAPAction-Eigenschaften. Diese Aktionen veranschaulicht das folgende Codebeispiel:
// Web-Service-Client initialisieren
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// SOAPAction-Eigenschaften konfigurieren
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");
// WSSGenerationContext initialisieren
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(samlToken);
- Initialisieren Sie den WSSGenerationContext. Das folgende Codefragment veranschaulicht die Verwendung des
gencont-Objekts vom Typ
WSSGenerationContext für die Initialisierung eines Generierungskontexts für das Einfügen des
SAMLToken in eine Web-Service-Anforderungsnachricht.
// WSSGenerationContext initialisieren
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(samlToken);
Speziell der Methodenaufruf
gencont.add(samlToken) gibt an, dass
das SAML-Token in eine Anforderungsnachricht eingefügt werden soll. Diese Operation erfordert, dass
der Clientcode über die folgende Java-2-Sicherheitsberechtigung verfügt:
“permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- Fügen Sie ein X.509-Token für den Nachrichtenschutz hinzu.
Im folgenden Beispielcode werden die Schlüsseldatei
dsig-sender.ks und der Beispielschlüssel SOAPRequester verwendet. In einer Produktionsumgebung dürfen Sie den Beispielschlüssel nicht verwenden. Das folgende
Codefragment veranschaulicht das Hinzufügen von eines X.509-Tokens für den Nachrichtenschutz.
// X.509-Token für Nachrichtenschutz hinzufügen
X509GenerateCallbackHandler x509callbackHandler = new X509GenerateCallbackHandler(
null,
"Profilstammverzeichnis/etc/ws-security/samples/dsig-sender.ks",
"JKS",
"client".toCharArray(),
"soaprequester",
"client".toCharArray(),
"CN=SOAPRequester, OU=TRL, O=IBM, ST=Kanagawa, C=JP", null);
SecurityToken x509 = factory.newSecurityToken(X509Token.class,
x509callbackHandler, "system.wss.generate.x509");
WSSSignature sig = factory.newWSSSignature(x509);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(samlToken);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
- Erstellen Sie ein WSSSignature-Objekt mit dem X509-Token. Die folgende Codezeile erstellt ein WSSSignature-Objekt mit dem
X509-Token:
WSSSignature sig = factory.newWSSSignature(x509);
- Fügen Sie den signierten Teil für den Nachrichtenschutz hinzu. Die folgende Codezeile gibt an, dass WSSSignature.BODY
als signierter Teil hinzugefügt werden soll:
sig.addSignPart(WSSSignature.BODY);
- Fügen Sie zum Sicherheitsheader von SOAP-Nachrichten das Element timestamp hinzu. Die Richtliniensätze SAML20 SenderVouches WSHTTPS und
SAML11 SenderVouches
WSHTTPS erfordern, dass Web-Service-Anforderungsnachrichten und -Antwortnachrichten im Sicherheitsheader von SOAP-Nachrichten ein Element
timestamp enthalten.
Im folgenden Codefragment generiert der Methodenaufruf factory.newWSSTimestamp() die Zeitmarke
(timestamp) und der Methodenaufruf gencont.add(timestamp) fügt die Zeitmarke
in die Anforderungsnachricht ein:
// Zeitmarke hinzufügen
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- Konfigurieren Sie die Verifizierung der digitalen Signatur in der Antwortnachricht.
Zum Angeben des
Umsetzungsalgorithmus SecurityTokenReference ist ein separater Teil WSSSignPart erforderlich, der
vom Attribut
WSSSignPart.TRANSFORM_STRT10 repräsentiert wird. Ein SAML-Token kann nicht direkt digital signiert werden. Mithilfe dieses Attributs
kann die Web-Services-Security-Laufzeitumgebung ein Element
SecurityTokenReference generieren, das auf das SAML-Token verweist und das Token mit der
SecurityTokenReference-Umsetzung digital signiert.
Die folgende Codezeile gibt an, dass das Attribut
WSSSignPart.TRANSFORM_STRT10 verwendet werden soll:
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(samlToken);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
- Fügen Sie das Objekt WSSGenerationContext zum Web-Service-Objekt
RequestContext hinzu. Das Objekt WSSGenerationContext enthält jetzt alle Sicherheitsinformationen, die für das Formatieren einer
Anforderungsnachricht erforderlich sind. Der Methodenaufruf gencont.process(requestContext) ordnet
das Objekt WSSGenerationContext dem Web-Service-Objekt
RequestContext zu, damit die Web-Services-Security-Laufzeitumgebung
den erforderlichen SOAP-Sicherheitsheader formatieren kann. Beispiel:
// Objekt WSSGenerationContext zum Web-Service-Objekt RequestContext hinzufügen
gencont.process(requestContext);
- Validieren Sie die digitale Signatur und die Integrität der Antwortnachricht mit dem X.509-Token. Falls die Providerrichtlinie vorschreibt, dass die Antwortnachricht digital signiert sein soll, müssen
Sie das
X.509-Token initialisieren.
- Ein Objekt X509ConsumeCallbackHandler wird mit einem Truststore, der Datei
dsig-receiver.ks und einem Zertifikatspfadobjekt initialisiert, um die digitale Signatur des Providers
zu validieren. Das Objekt
X509ConsumeCallbackHandler wird mit der folgenden Codezeile initialisiert:
X509ConsumeCallbackHandler callbackHandlerVer = new X509ConsumeCallbackHandler(
"profile_root/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
- Ein Verifizierungsobjekt WSSVerification wird erstellt, zu dem der Nachrichtenhauptteil hinzugefügt wird, damit
die Web-Services-Security-Laufzeitumgebung die digitale Signatur validiert.
Das Objekt
WSSVerification wird mit der folgenden Codezeile initialisiert:
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
Das Objekt WSSConsumingContext enthält jetzt alle Sicherheitsinformationen, die für das Formatieren einer
Anforderungsnachricht erforderlich sind. Der Methodenaufruf
concont.process(requestContext) ordnet das Objekt
WSSConsumingContext der Antwortmethode zu.
Beispiel:
// Objekt WSSConsumingContext zum Web-Service-Objekt RequestContext hinzufügen
concont.process(requestContext);
Ergebnisse
Sie haben ein selbst ausgestelltes SAML-Token mit der Bestätigungsmethode Sender-Vouches
erstellt und dieses dann mit Web-Service-Anforderungsnachrichten über das
JAX-WS-Programmiermodell und WSS-APIs gesendet.
Beispiel
Das folgende Codebeispiel ist eine vollständige, sofort einsatzfähige
Web-Service-Clientanwendung, die veranschaulicht, wie ein selbst ausgestelltes
SAML-Sender-Vouches-Token erstellt und in Web-Service-Anforderungsnachrichten gesendet
wird. Dieser Beispielcode veranschaulicht die oben beschriebenen Prozedurschritte.
/**
* Der folgende Quellcode ist von der IBM Corporation erstellter Beispielcode, der
* mit der Einschränkung bereitgestellt wird, dass er nur zur Unterstützung für die Nutzung
* der Technologie verwendet werden darf. Der Code wird ohne Wartung (auf "as-is"-Basis) und
* ohne Gewährleistung zur Verfügung gestellt. IBM ist nicht haftbar für Schäden, die Ihnen aus
* der Nutzung des Beispielcodes entstehen, selbst wenn IBM auf die Möglichkeit solche
* Schäden hingewiesen wurde.
*/
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.callbackhandler.SAMLGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.WSSConsumingContext;
import com.ibm.websphere.wssecurity.wssapi.WSSFactory;
import com.ibm.websphere.wssecurity.wssapi.WSSGenerationContext;
import com.ibm.websphere.wssecurity.wssapi.WSSTimestamp;
import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
import com.ibm.websphere.wssecurity.callbackhandler.X509ConsumeCallbackHandler;
import com.ibm.websphere.wssecurity.callbackhandler.X509GenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.WSSException;
import com.ibm.websphere.wssecurity.wssapi.signature.WSSSignPart;
import com.ibm.websphere.wssecurity.wssapi.signature.WSSSignature;
import com.ibm.websphere.wssecurity.wssapi.verification.WSSVerification;
import com.ibm.websphere.wssecurity.wssapi.token.X509Token;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.saml.config.SamlConstants;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertStore;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
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()
*
* Befehlszeilenargumente siehe printusage()
*
* @param args
*/
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* CallService-Parameter wurden gelesen. Jetzt können die Serviceproxyklassen aufgerufen werden.
*
*/
void CallService() {
String response = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config", "Profilstammverzeichnis/properties/wsjaas.conf");
// WSSFactory-Objekt initialisieren
WSSFactory factory = WSSFactory.getInstance();
// WSSGenerationContext initialisieren
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
// SAML-Token erstellen
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());
// Web-Service-Client initialisieren
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// SOAPAction-Eigenschaften konfigurieren
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");
// WSSGenerationContext initialisieren
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(samlToken);
// X.509-Token für Nachrichtenschutz hinzufügen
X509GenerateCallbackHandler x509callbackHandler = new X509GenerateCallbackHandler(
null,
"Profilstammverzeichnis/etc/ws-security/samples/dsig-sender.ks",
"JKS",
"client".toCharArray(),
"soaprequester",
"client".toCharArray(),
"CN=SOAPRequester, OU=TRL, O=IBM, ST=Kanagawa, C=JP", null);
SecurityToken x509 = factory.newSecurityToken(X509Token.class,
x509callbackHandler, "system.wss.generate.x509");
WSSSignature sig = factory.newWSSSignature(x509);
sig.setSignatureMethod(WSSSignature.RSA_SHA1);
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(samlToken);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
// Zeitmarke hinzufügen
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
// Verarbeitung der Zeitmarke in der Antwortnachricht vorbereiten
concont.add(WSSConsumingContext.TIMESTAMP);
// Verfizierung der digitalen Signatur in der Antwortnachricht vorbereiten
X509Certificate x509cert = null;
try {
InputStream is = new FileInputStream("Profilstammverzeichnis/etc/ws-security/samples/intca2.cer");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
x509cert = (X509Certificate) cf.generateCertificate(is);
} catch(FileNotFoundException e1){
throw new WSSException(e1);
} catch (CertificateException e2) {
throw new WSSException(e2);
}
Set<Object> eeCerts = new HashSet<Object>();
eeCerts.add(x509cert);
java.util.List<CertStore> certList = new java.util.ArrayList<CertStore>();
CollectionCertStoreParameters certparam = new CollectionCertStoreParameters(eeCerts);
CertStore cert = null;
try {
cert = CertStore.getInstance("Collection", certparam, "IBMCertPath");
} catch (NoSuchProviderException e1) {
throw new WSSException(e1);
} catch (InvalidAlgorithmParameterException e2) {
throw new WSSException(e2);
} catch (NoSuchAlgorithmException e3) {
throw new WSSException(e3);
}
if(certList != null ){
certList.add(cert);
}
X509ConsumeCallbackHandler callbackHandlerVer = new X509ConsumeCallbackHandler(
"Profilstammverzeichnis/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
ver.addRequiredVerifyPart(WSSVerification.BODY);
concont.add(ver);
gencont.process(requestContext);
concont.process(requestContext);
// Eingabeobjekt erstellen
EchoStringInput echoParm =
new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
echoParm.setEchoInput(input);
System.out.println(">> CLIENT: SEI Echo to " + endpointURL);
// Service aufrufen
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();
}
}
}
Wenn diese Beispiel-Web-Service-Clientanwendung ordnungsgemäß ausgeführt wird, empfangen Sie
Nachrichten wie die folgenden:
SAMLToken id = _6CDDF0DBF91C044D211271166233407
Retrieving document at 'file:Profilstammverzeichnis/.../wsdl/'.
>> CLIENT: SEI Echo to http://localhost:9080/WSSampleSei/EchoService12
>> CLIENT: SEI Echo invocation complete.
>> CLIENT: SEI Echo response is: SOAP12==>>HELLO