Envoi d'un jeton de sécurité à l'aide d'API WSS avec un module de connexion de jeton de sécurité générique

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

  1. 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 :

    1. Téléchargez l'exemple d'application JaxWSServicesSamples. Le modèle d'application JaxWSServicesSamples n'est pas installé par défaut.
    2. 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.

    3. 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é.

    4. 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).
    5. 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).
    6. 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 :
      1. Cliquez sur Services > Ensembles de règles > Liaisons générales de l'ensemble de règles du fournisseur > Saml Bearer Provider sample > WS-Security > Authentification et protection.
      2. Cliquez sur con_saml11token dans la table des jetons d'authentification.
      3. Cliquez sur Gestionnaire d'appel.
      4. 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.
  2. 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");
  3. 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.
  4. 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 ");
  5. Ajoutez le jeton d'authentification demandé au STS à l'en-tête de sécurité SOAP des messages de demande de services Web.
    1. 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);
    2. 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"
  6. 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);
    1. 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);
    2. 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);
    3. 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();
    4. 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);
    5. 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);
  7. 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.
    1. 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"));
    2. 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();
        }
    }
}

Icône indiquant le type de rubrique Rubrique de tâche



Icône d'horodatage Dernière mise à jour: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_propagatingsectoken_wssapi_glm
Nom du fichier : twbs_propagatingsectoken_wssapi_glm.html