Vous pouvez demander un jeton d'authentification à un STS (Security
Token Service) externe, puis l'envoyer avec les messages de demande de services Web
à l'aide du modèle de programmation JAX-WS (Java™ API
for XML-Based Web Services) et des API WSS (Web Services Security) avec protection
au niveau du transport ou des messages.
Avant de commencer
On considère ici que vous connaissez le modèle de programmation JAX-WS,
les API WSS, les modules de connexion du jeton de sécurité générique de la
sécurité des services Web de WebSphere, la protection du transport SSL, la protection au
niveau des messages et l'utilisation des ensembles de règles pour configurer et
administrer les paramètres des services Web.
Pourquoi et quand exécuter cette tâche
L'application client de services Web utilisée dans cette tâche est une version modifiée du code client contenu dans l'application modèle JaxWSServicesSamples disponible pour le téléchargement.
Des exemples de code du modèle
sont décrits dans la procédure et un modèle de client de service Web prêt à
l'emploi est fourni.
Effectuez les étapes suivantes pour
demander un jeton d'authentification SAML Bearer à un STS externe et
l'envoyer :
Procédure
- Identifiez et obtenez le client de service Web que vous souhaitez utiliser pour appeler un fournisseur de service Web. Utilisez ce client pour demander et insérer des jetons d'authentification
dans les messages de demande SOAP à l'aide de programmes, dans les API WSS. Le client de services Web utilisé dans cette procédure
est une version modifiée du code client contenu dans l'exemple d'application
de services Web JaxWSServicesSamples.
Pour obtenir le modèle de client de service Web et le modifier en ajoutant les API de Services de sécurité (WSS), afin de programmer la transmission de jetons de sécurité dans le message de demande SOAP, procédez comme suit :
- Téléchargez l'exemple d'application JaxWSServicesSamples. Le modèle d'application JaxWSServicesSamples n'est pas installé par défaut.
- Obtenez le code client JaxWSServicesSamples. Pour les besoins de cet exemple, cette procédure utilise une version
modifiée du client léger Echo compris dans le modèle JaxWSServicesSamples. Le fichier du modèle de client léger de service Web Echo, SampleClient.java,
est situé dans le répertoire src\SampleClientSei\src\com\ibm\was\wssample\sei\cli. L'exemple de fichier de classe est inclus au fichier WSSampleClientSei.jar.
L'application d'entreprise JaxWSServicesSamples.ear
et la prise en charge des fichiers d'archive Java
(JAR) sont situés dans le répertoire installableApps
dans l'exemple d'application JaxWSServicesSamples.
- Déployez le fichier JaxWSServicesSamples.ear
dans le serveur d'application. Une fois le fichier JaxWSServicesSamples.ear déployé, vous êtes prêt à tester le modèle de code de client de services Web avec le modèle d'application.
Au lieu d'utiliser l'ensemble de règles de la protection de
l'exemple de client de services Web, vous pouvez choisir d'intégrer à votre
propre application client de services Web les fragments de code destinés à
programmer la transmission des jetons d'authentification dans le messages de
demande SOAP à l'aide des API WSS. L'exemple pris dans
cette procédure utilise un client léger de service Web JAX-WS ; il est
cependant possible d'utiliser un client géré.
- Associez l'ensemble de règles SAML11 Bearer WSHTTPS Default au fournisseur de services Web. Cet ensemble de règles sert à protéger les messages à l'aide du transport HTTPS. Pour plus d'informations sur la façon d'associer l'ensemble de règles par
défaut SAML11 Bearer WSHTTPS Default au fournisseur de services Web,
reportez-vous à la section relative à la configuration des clients et des
fournisseurs pour le jeton SAML bearer (porteur).
- Associez les liaisons générales par défaut du modèle SAML Bearer Provider Sample au modèle de fournisseur de services Web. Pour plus d'informations sur la façon d'affecter les liaisons générales par défaut du modèle par défaut SAML Bearer Provider Default à votre application de services Web, reportez-vous à la section relative à la configuration des clients et des fournisseurs pour le jeton SAML bearer (porteur).
- Vérifiez que les propriétés personnalisées trustStoreType,
trustStorePassword et trustStorePath correspondent au fichier de clés
certifiées contenant le certificat de signataire de STS. Procédez comme suit dans la console d'administration :
- Cliquez sur .
- Cliquez sur con_saml11token dans la table des jetons d'authentification.
- Cliquez sur Gestionnaire d'appel.
- Dans la section Propriétés personnalisées, vérifiez que les propriétés personnalisées trustStoreType,
trustStorePassword et trustStorePath correspondent au fichier de clés
certifiées contenant le certificat de signataire de STS.
- Si vous utilisez la protection au niveau du transport SSL pour
protéger la demande de service Web ou la demande WS-Trust, utilisez la
propriété JVM ci-après pour la configuration de SSL.
-Dcom.ibm.SSL.ConfigURL=file:<profile_root>\properties\ssl.client.props
A la place, vous pouvez également définir le fichier de configuration SSL en
définissant une propriété système Java
dans le modèle de code client :
System.setProperty("com.ibm.SSL.ConfigURL", "file:racine_profil/properties/ssl.client.props");
- Ajoutez le fichier JAR du client léger JAX-WS au chemin d'accès aux classes : app_server_root/runtimes/com.ibm.jaxws.thinclient_8.5.0.jar. Pour plus d'informations sur l'ajout de ce fichier JAR au chemin d'accès
aux classes, consultez la rubrique relative au test des clients compatibles
avec les services Web.
- Demandez le jeton d'authentification à un STS externe. Le fragment de code suivant montre comment demander le jeton
d'authentification à utiliser avec le module de connexion SecurityToken
générique de WebSphere et suppose
qu'un STS externe est configuré pour accepter un jeton Username comme jeton
d'authentification et émettre un jeton SAML 1.1.
//Demander un jeton de sécurité au STS externe :
WSSFactory factory = WSSFactory.getInstance();
//URL STS qui émet le jeton demandé
String STS_URI = "https://externalstsserverurl:port/TrustServerWST13/services/RequestSecurityToken";
//Noeud final des services Web qui reçoit le jeton émis
String ENDPOINT_URL = "http://localhost:9080/WSSampleSei/EchoService";
//Début de l'exemple de code 1 (Utilisation d'une émission WS-Trust pour demander le jeton
//au STS dans lequel le jeton d'authentification est envoyé via un en-tête WS-Security ) :
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//La propriété suivante indique que la demande ws-trust doit être
//conforme à la spécification WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//Cette demande n'est effectuée qu'avec une émission WS-TRust (sans l'utilisation de
//WS-Trust Validate)
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Créer l'objet de contexte de la demande WS-Trust :
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Utiliser UNT pour l'authentification des demandes sécurisées
UNTGenerateCallbackHandler utCallbackHandler = new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Fin de l'exemple de code 1.
//Début de l'exemple de code 2 (utilisation de WS-Trust Validate pour demander un jeton
//en échangeant un jeton dans le sujet RunAs)
//Si le client de service Web possède un sujet RunAs, par exemple, un
//serveur intermédiaire authentifié sert de client pour appeler le
//service en aval, vous pouvez programmer le client pour qu'il utilise le jeton
//du sujet RunAs pour l'échanger avec le STS à l'aide de WS-Trust Validate.
//Pour cela, remplacez l'exemple de code 1 par le code suivant :
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
//Cette demande est effectuée avec WS-Trust 1.3
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
//ajoutez la ligne ci-après si vous ne souhaitez pas rétromigrer vers une émission WS-Trust
//en cas d'échec de l'échange de jeton.
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY, "true");
//ajoutez la ligne ci-après pour spécifier le type de jeton dans le sujet RunAs qui
//sera utilisé pour échanger le jeton demandé. Par exemple, utilisez
//le jeton LTPA pour l'échanger contre un jeton SAML. Si le jeton échangé
//dans le sujet RunAs possède le même type de valeur que le jeton demandé,
//il n'est pas nécessaire de définir IssuedTokenConfigConstants.USE_TOKEN.
cbackMap1.put(IssuedTokenConfigConstants.USE_TOKEN, LTPAToken.ValueType);
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Les codes ci-après sont ajoutés si le jeton d'authentification dans l'en-tête ws-security
//ou la sécurité au niveau des messages est requis. En l'absence de
//protection au niveau des messages ou de jeton d'authentification supplémentaire pour
//WS-Trust Validate, ne créez pas l'objet de contexte illustré ci-après.
//Objet de contexte de la demande WS-Trust :
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Utiliser UNT pour l'authentification des demandes sécurisées
UNTGenerateCallbackHandler utCallbackHandler =
new UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Fin de l'exemple de code 2.
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
//L'étape ci-après permettant de définir ValueType est requise.
//Le paramètre correspond toujours au QName du type de valeur du jeton demandé.
//QName pour SAML1.1 :
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//Inclut les définitions QName pour le jeton SAML11, SAML20, TAM
//et le jeton PassTicket.
//QName pour SAML 2.0 :
QName Saml20ValueType = new QName(WSSConstants.SAML.SAML20_VALUE_TYPE);
token.setValueType(Saml11ValueType);
//QName pour jeton TAM :
QName TamValueType = new QName("http://ibm.com/2004/01/itfim/ivcred");
//QName pour jeton PassTicket :
QName PassTicketValueType = new QName("http://docs.oasis-open.org/wss/
2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
//Vous pouvez utiliser l'interface du jeton afin d'obtenir le QName ValueType pour
//tous les autres jetons. Par exemple, le QName d'un jeton Username est
//UsernameToken.ValueType.
L'objet GenericIssuedTokenGenerateCallbackHandler contient
les paramètres qui définissent les caractéristiques du jeton de sécurité que
vous demandez, ainsi que les paramètres requis pour atteindre le STS et obtenir
le jeton de sécurité. L'objet GenericIssuedTokenGenerateCallbackHandler spécifie les paramètres de configuration décrits
dans le tableau ci-dessous :
Tableau 1. Propriétés GenericIssuedTokenGenerateCallbackHandler. Ce tableau décrit les paramètres de configuration de l'objet GenericIssuedTokenGenerateCallbackHandler et il indique si la propriété est requise ou non.Propriété |
Description |
Obligatoire |
IssuedTokenConfigConstants.STS_ADDRESS |
Indique l'adresse http du STS. Si les
communications avec le STS sont protégées par SSL, vous devez définir la
propriété -Dcom.ibm.SSL.ConfigURL. La connexion SSL au STS est indiquée par un préfixe d'adresse https://.
|
Oui |
IssuedTokenConfigConstants.APPLIES_TO |
Indique l'adresse du service cible pour laquelle vous
souhaitez utiliser le jeton. |
Non |
IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST |
Indique si le système doit demander au STS
un jeton unique imbriqué dans un élément RequestSecurityToken (RST) ou
plusieurs jetons d'une collection d'éléments RST imbriqués dans un seul élément RequestSecurityTokenCollection (RSTC). Le comportement par défaut consiste à demander un jeton unique imbriqué
dans un élément RequestSecurityToken (RST) au STS.
Si
vous spécifiez la valeur true pour cette propriété, plusieurs jetons
d'une collection d'éléments RST imbriqués dans un seul élément
RequestSecurityTokenCollection (RSTC) sont demandés au STS.
La valeur par défaut est false.
|
Non |
IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE |
Spécifie l'espace de nom WS-Trust inclus dans la demande
WS-Trust. La valeur par défaut est WSTrust 1.3.
|
Non |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT |
Indiquez si vous souhaitez que WS-Security utilise le
jeton du sujet RunAs pour échanger le jeton demandé en utilisant d'abord WS-Trust Validate. Si
la valeur est false, WS-Security utilise une émission
WS-Trust pour demander le jeton. La valeur par défaut est true.
|
Non |
IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT_ONLY |
Indiquez si vous ne souhaitez pas que WS-Security utilise
une émission WS-Trust au jeton demandé en cas d'échec de l'échange de jeton. La valeur par défaut est false.
|
Non |
IssuedTokenConfigConstants.USE_TOKEN |
Utilisez cette valeur afin de choisir un jeton du sujet
RunAs pour échanger le jeton demandé. La valeur par défaut est le
ValueType du jeton demandé.
|
Non |
Une instance WSSGenerationContext et une instance
WSSConsumingContext sont également définies dans l'objet GenericIssuedTokenGenerateCallbackHandler. Dans cet exemple, l'instance WSSGenerationContext contient un
objet UNTGenerateCallbackHandler avec les informations permettant de créer l'élément UsernameToken à envoyer au STS.
Le paramètre
system.wss.generate.issuedToken définit le
module de connexion JAAS (Java
Authentication and Authorization Service) utilisé pour créer le jeton de
sécurité générique. Vous devez spécifier une propriété JVM pour définir un fichier de configuration JAAS contenant la configuration requise pour la connexion JAAS, par exemple :
-Djava.security.auth.login.config=profile_root/properties/wsjaas_client.conf
A la place, vous pouvez également spécifier un fichier de configuration de la connexion JAAS en définissant une propriété système Java dans le modèle de code client, par exemple :
System.setProperty("java.security.auth.login.config", "racine_profil/properties/wsjaas_client.conf ");
- Ajoutez le jeton d'authentification demandé au STS à l'en-tête de sécurité
SOAP des messages de demande de services Web.
- Initialisez le client de services Web et configurez les propriétés SOAPAction. Le code suivant illustre ces actions :
// Initialiser le client de service Web
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configurer les propriétés SOAPAction
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");
// Initialiser WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
- Initialisez l'objet WSSGenerationContext. Le code ci-après illustre l'utilisation de la méthode
WSSFactory.newWSSGenerationContext pour
obtenir un objet WSSGenerationContext. L'objet
WSSGenerationContext est ensuite utilisé pour insérer le jeton
dans un message de demande de service Web :
// Initialiser WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
Pour la méthode WSSGenerationContext.add, le code client doit disposer du
droit d'accès Java 2 suivant :permission javax.security.auth.AuthPermission "modifyPrivateCredentials"
- Ajoutez un jeton X.509 pour la protection des messages (ignorez cette étape
si le service Web n'est protégé que par la protection au niveau du transport SSL). L'exemple de code ci-après utilise le fichier de clés
dsig-sender.ks et l'exemple de clé SOAPRequester. N'utilisez pas le modèle clé dans un environnement de production. Le
code suivant illustre l'ajout d'un jeton X.509 pour la protection des messages :
// Ajouter un jeton X.509 pour la protection des messages
X509GenerateCallbackHandler x509callbackHandler = new X509GenerateCallbackHandler(
null,
"profile_root/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(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
sig.addSignPart(sigPart);
sig.addSignPart(WSSSignature.BODY);
- Créez un objet WSSSignature avec le jeton X.509. La ligne de code ci-dessous crée un objet WSSSignature avec le jeton X.509 :
WSSSignature sig = factory.newWSSSignature(x509);
- Ajoutez la portion signée à utiliser pour la protection des messages. La ligne de code qui suit définit l'ajout de WSSSignature.BODY comme
portion signée :
sig.addSignPart(WSSSignature.BODY);
- Ajoutez l'élément Timestamp dans l'en-tête de sécurité des messages SOAP. Les ensembles de règles SAML20 SenderVouches WSHTTPS et SAML11
SenderVouches WSHTTPS requièrent que les demandes et réponses de
service Web contiennent un élément Timestamp dans l'en-tête de
sécurité SOAP. Dans le code suivant, la méthode WSSFactory.newWSSTimestamp() génère un élément
Timestamp et la méthode WSSGenerationContext.add(timestamp) ajoute l'élément
Timestamp au message de demande :
// Ajouter l'élément Timestamp
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
sig.addSignPart(WSSSignature.TIMESTAMP);
gencont.add(sig);
WSSConsumingContext concont = factory.newWSSConsumingContext();
- Ignorez cette étape si la signature du jeton n'est pas requise. Si le
jeton de sécurité demandé doit être signé avec l'option de référence STR
Dereference Transform, suivez l'étape 1. Sinon,
suivez l'étape 2. l'option de référence STR Dereference Transform
est généralement appelée STR-Transform.
Etape 1 : Certains jetons, et notamment les jetons SAML, ne peuvent pas
être directement signés numériquement. Vous devez signer le jeton à l'aide de STR-Transform. Pour qu'un jeton soit signé avecSTR-Transform, il doit être
référencé par un élément <wsse:SecurityTokenReference>
dans le bloc d'en-tête <wsse:Security>. Pour signer un
jeton de sécurité avec STR-Transform, un objet
WSSSignPart distinct est créé pour spécifier l'élément
SecurityTokenReference avec un algorithme de transformation
représenté par l'attribut WSSSignPart.TRANSFORM_STRT10. Cet attribut permet à l'environnement d'exécution de WS-Security de générer un élément
SecurityTokenReference pour référencer le jeton et le signer
numériquement à l'aide de l'option de référence STR Dereference. Le
code suivant illustre l'utilisation de l'attribut WSSSignPart.TRANSFORM_STRT10 :
WSSSignPart sigPart = factory.newWSSSignPart();
sigPart.setSignPart(token);
sigPart.addTransform(WSSSignPart.TRANSFORM_STRT10);
Etape 2 : Si le
jeton signé demandé ne correspond pas à un jeton SAML ou que
STR-Transform n'est pas utilisé, utilisez le code suivant à la
place :sig.addSignPart(token);
- Associez l'objet WSSGenerationContext à l'objet
RequestContext des services Web. L'objet WSSGenerationContext contient désormais toutes les informations de sécurité nécessaires au formatage d'un message de demande. La
méthode WSSGenerationContext.process(requestContext) associe
l'objet WSSGenerationContext à l'objet
RequestContext des services Web pour permettre à l'environnement d'exécution de WS-Security
de mettre en forme l'en-tête de sécurité SOAP requis. Par exemple :
// Associe l'objet WSSGenerationContext à l'objet de services Web RequestContext.
gencont.process(requestContext);
- Utilisez le jeton X.509 pour valider la signature numérique et l'intégrité
du message de réponse si la règle du fournisseur requiert une signature numérique
pour le message de réponse. Ignorez cette étape si vous utilisez une protection au niveau du transport SSL.
- Un objet X509ConsumeCallbackHandler est initialisé
avec un fichier de clés certifiées et une Liste d'objets de
chemin de certificat pour valider la signature numérique dans un message de
réponse. Le code suivant initialise l'objet X509ConsumeCallbackHandler avec le fichier de clés certifiées
dsig-receiver.ks et un objet de chemin de certificat
appelé certList :
ArrayList certList = new ArrayList();
java.security.cert.CertStore certStore = java.security.cert.CertStore.getDefaultType();
certList.add(certStore);
X509ConsumeCallbackHandler callbackHandlerVer = new
X509ConsumeCallbackHandler("profile_root/etc/ws-security/samples/dsig-receiver.ks",
"JKS",
"server".toCharArray(),
certList,
java.security.Security.getProvider("IBMCertPath"));
- Un objet WSSVerification est créé et le corps du message
est ajouté à l'objet de vérification, pour que l'environnement d'exécution de
WS-Security valide la signature numérique. Le code suivant permet d'initialiser l'objet WSSVerification :
WSSVerification ver = factory.newWSSVerification(X509Token.class, callbackHandlerVer);
L'objet WSSConsumingContext contient désormais toutes les informations de
sécurité nécessaires au formatage d'un message de demande. La méthode
WSSConsumingContext.process(requestContext) associe l'objet
WSSConsumingContext à la méthode de la réponse. Par exemple :// Associe l'objet WSSConsumingContext à
l'objet de services Web RequestContext.
concont.process(requestContext);
Résultats
Vous avez demandé un jeton de sécurité à un STS externe. Après avoir obtenu le jeton, vous l'avez envoyé avec des
messages de demande de services Web à l'aide de la protection au niveau des
messages du modèle de programmation JAX-WS et des API WSS.
Exemple
L'exemple de code qui suit est une application de client de
services Web qui illustre le mode de demande d'un jeton SAML Bearer à un
STS externe et d'envoi dans un message de demande de service Web. Si votre scénario d'utilisation requiert des jetons SAML, mais ne nécessite pas
que l'application les transmette par l'intermédiaire des messages de service
Web, n'utilisez que la première partie du modèle de code, jusqu'à la section
// Initialiser le client de services Web.
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.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.SecurityToken;
import com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
import com.ibm.websphere.wssecurity.callbackhandler.UNTGenerateCallbackHandler;
import com.ibm.wsspi.wssecurity.core.token.config.WSSConstants;
import com.ibm.wsspi.wssecurity.core.config.IssuedTokenConfigConstants;
import com.ibm.websphere.wssecurity.callbackhandler.GenericIssuedTokenGenerateCallbackHandler;
import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityToken;
import javax.xml.namespace.QName;
import java.util.HashMap;
import java.util.Map;
import javax.xml.ws.BindingProvider;
public class SampleSamlSVClient {
private String urlHost = "yourhost";
private String urlPort = "9444";
private static final String CONTEXT_BASE = "/WSSampleSei/";
private static final String ECHO_CONTEXT12 = CONTEXT_BASE+"EchoService12";
private String message = "HELLO";
private String uriString = "https://" + urlHost + ":" + urlPort;
private String endpointURL = uriString + ECHO_CONTEXT12;
private String input = message;
/**
* main()
*
* voir printusage() pour les arguments de ligne de commande
*
* @param args
*/
public static void main(String[] args) {
SampleSamlSVClient sample = new SampleSamlSVClient();
sample.CallService();
}
/**
* Les paramètres CallService ont déjà été lus. Appeler les classes de proxy de service
*
*/
void CallService() {
String response = "ERROR!:";
try {
System.setProperty("java.security.auth.login.config",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/wsjaas_client.conf ");
System.setProperty("com.ibm.SSL.ConfigURL",
"file:/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/properties/ssl.client.props");
//Demande du jeton SAML à un STS externe
WSSFactory factory = WSSFactory.getInstance();
String STS_URI = "https://yourhost:9443/TrustServerWST13/services/RequestSecurityToken";
String ENDPOINT_URL = "http://localhost:9081/WSSampleSei/EchoService12";
HashMap<Object, Object> cbackMap1 = new HashMap<Object, Object>();
cbackMap1.put(IssuedTokenConfigConstants.STS_ADDRESS, STS_URI);
cbackMap1.put(IssuedTokenConfigConstants.APPLIES_TO, ENDPOINT_URL);
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_WSTRUST_NAMESPACE,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512");
cbackMap1.put(IssuedTokenConfigConstants.TRUST_CLIENT_COLLECTION_REQUEST, "false");
cbackMap1.put(IssuedTokenConfigConstants.USE_RUN_AS_SUBJECT, "false");
GenericIssuedTokenGenerateCallbackHandler cbHandler1 =
new GenericIssuedTokenGenerateCallbackHandler (cbackMap1);
//Objet de contexte de la demande WS-Trust :
WSSGenerationContext gencont1 = factory.newWSSGenerationContext();
WSSConsumingContext concont1 = factory.newWSSConsumingContext();
// Utiliser UNT pour l'authentification des demandes sécurisées
UNTGenerateCallbackHandler utCallbackHandler = new
UNTGenerateCallbackHandler("testuser", "testuserpwd");
SecurityToken ut = factory.newSecurityToken(UsernameToken.class, utCallbackHandler);
gencont1.add(ut);
cbHandler1.setWSSConsumingContextForTrustClient(concont1);
cbHandler1.setWSSGenerationContextForTrustClient(gencont1);
//Obtenir le jeton de sécurité générique
GenericSecurityToken token = (GenericSecurityToken) factory.newSecurityToken
(GenericSecurityToken.class, cbHandler1, "system.wss.generate.issuedToken");
QName Saml11ValueType = new QName(WSSConstants.SAML.SAML11_VALUE_TYPE);
token.setValueType(Saml11ValueType);
System.out.println("SAMLToken id = " + token.getId());
// Initialiser le client de services Web
EchoService12PortProxy echo = new EchoService12PortProxy();
echo._getDescriptor().setEndpoint(endpointURL);
// Configurer les propriétés SOAPAction
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");
// Initialiser WSSGenerationContext
WSSGenerationContext gencont = factory.newWSSGenerationContext();
gencont.add(token);
// Ajouter l'horodatage
WSSTimestamp timestamp = factory.newWSSTimestamp();
gencont.add(timestamp);
gencont.process(requestContext);
// Générer l'objet d'entrée
EchoStringInput echoParm =
new com.ibm.was.wssample.sei.echo.ObjectFactory().createEchoStringInput();
echoParm.setEchoInput(input);
System.out.println(">> CLIENT: SEI Echo to " + endpointURL);
// Préparer la consommation de l'horodatage dans le message de réponse
WSSConsumingContext concont = factory.newWSSConsumingContext();
concont.add(WSSConsumingContext.TIMESTAMP);
concont.process(requestContext);
// Appeler le 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();
}
}
}