Génération et consommation de jetons personnalisés avec les modules de connexion générique

Le générateur et le consommateur émis génériques, GenericIssuedTokenGenerateLoginModule et GenericIssuedTokenConsumeLoginModule, peuvent être utilisés avec les SPI GenericSecurityTokenFactory et GenericSecurityToken pour implémenter une solution de bout en bout pour un jeton personnalisé. La génération et la consommation de jetons personnalisés avec les modules de connexion Generic Issue Login Modules peuvent être exécutées avec une règle et des liaisons ou des WSSAPI.

Avant de commencer

Vous devez disposer d'un ensemble d'applications client fournisseur JAX-WS auxquelles vous ajoutez de nouvelles classes de module de connexion JAAS.

Pourquoi et quand exécuter cette tâche

Exécutez les étapes suivantes pour activer un groupe d'application client et fournisseur de service JAX-WS à utiliser comme jeton personnalisé. Dans ces étapes, MyToken représente le nom du jeton créé.

Lors de l'exécution de cette tâche :
  1. Deux modules de connexion JAAS sont créés ; un pour générer le jeton et un autre pour le consommer.
  2. Le jeton est généré et consommé avec l'assistance du consommateur et du générateur de jeton émis génériques.
  3. Les contraintes de sécurité sont ensuite appliquées aux applications avec les ensembles de règles et les liaisons.

Procédure

  1. Créez le module de connexion JAAS générateur suivant et rendez-le accessible au code d'application.
    package test.tokens;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Map;
    import javax.security.auth.Subject;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import javax.xml.soap.SOAPFactory;
    import javax.xml.soap.SOAPElement;
    import javax.xml.namespace.QName;
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
    
    public class MyCustomGenerator implements LoginModule {
    
      private Map _sharedState;
      private Map _options;
      private CallbackHandler _handler;
    
      public void initialize(Subject subject, CallbackHandler callbackHandler,
                             Map<String, ?> sharedState, Map<String, ?> options) {
    
        this._handler = callbackHandler;
        this._sharedState = sharedState;
        this._options = options;  
      }
      public boolean login() throws LoginException {
    
        GenericSecurityTokenFactory factory = null;
        try {
          factory = GenericSecurityTokenFactory.getInstance();
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (factory == null) {
          throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
        }
        SecurityToken myToken = null;
        try {
          SOAPElement tokenElement = createCustomElement(factory);
          myToken = factory.getToken(tokenElement, new QName("http://www.acme.com","MyToken"));
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (myToken == null) {
          throw new LoginException("myToken is null");
        }
    
        //Put the token in a list on the shared state where it will be available to be used by
        //stacked login modules
        factory.putGeneratorTokenToSharedState(_sharedState, myToken);
    
        return true;
      }
    
      private SOAPElement createCustomElement(GenericSecurityTokenFactory gstFactory) throws Exception {
        /*
          <acme:MyToken xmlns:acme="http://www.acme.com" 
                xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
            <acme:EMail>joe.smith@acme.com</acme:EMail>
          </acme:MyToken>
        */
        SOAPFactory factory = SOAPFactory.newInstance();
    
        //Create the MyToken element
        SOAPElement tokElement = factory.createElement("MyToken", "acme", "http://www.acme.com");
        //Add the Id attribute
        tokElement.addAttribute(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", "utl"), gstFactory.createUniqueId());
    
        //Create the Email element
        SOAPElement emailElement = factory.createElement("Email", "acme", "http://www.acme.com");
        emailElement.addTextNode("joe.smith@acme.com");
    
        //Add the EMail element to the MyToken
        tokElement.addChildElement(emailElement);
    
        return tokElement;
      }
    
      public boolean logout() throws LoginException {
        return false;
      } 
      public boolean abort() throws LoginException {
        return false;
      }
      public boolean commit() throws LoginException {
        return true;
      }
    }
  2. Créez le module de connexion JAAS consommateur suivant et rendez-le accessible au code d'application
    package test.tokens;
    
    import java.util.Map;
    import javax.xml.namespace.QName;
    import org.apache.axiom.om.OMElement;
    import javax.security.auth.Subject;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import com.ibm.websphere.wssecurity.callbackhandler.PropertyCallback;
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
    import com.ibm.wsspi.wssecurity.wssapi.OMStructure;
    
    public class MyCustomConsumer implements LoginModule {
    
      private CallbackHandler _handler;
      private Map _sharedState;
    
      public void initialize(Subject subject, CallbackHandler callbackHandler,
                             Map<String, ?> sharedState, Map<String, ?> options) {
        this._handler = callbackHandler;
        this._sharedState = sharedState;
      }
    
      public boolean login() throws LoginException {
        PropertyCallback propertyCallback = new PropertyCallback(null);
        Callback[] callbacks = new Callback[] { propertyCallback};
    
        try {
          this._handler.handle(callbacks);
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        //Get the GenericSecurityTokenFactory
        GenericSecurityTokenFactory factory = null;
        try {
          factory = GenericSecurityTokenFactory.getInstance();
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (factory == null) {
          throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
        }
        //Get the token that was consumed by the GenericIssuedConsumeLoginModule
        SecurityToken myToken = factory.getConsumerTokenFromSharedState(_sharedState, 
                                                                        new QName("http://www.acme.com","MyToken"));
    
        if (myToken == null) {
          throw new LoginException("no token");
        }
    
        //Get the token's element
        Object obj = myToken.getXML();
        if (obj == null) {
          throw new LoginException("token is empty");
        }
        if (!(obj instanceof OMStructure)) {
          throw new LoginException("XML is not OMStructure");
        }
        OMElement tokenElement = ((OMStructure)obj).getNode();
        //you can use the org.apache.axis2.util.XMLUtils.toDOM method
        //if you want to work with the a w3c.dom element instead of an
        //Axiom element
    
        //Do some processing on the contents of the token element
        OMElement el = tokenElement.getFirstChildWithName(new QName("http://www.acme.com","Email"));
        if (el == null) {
          throw new LoginException("no email element");
        }
        String value = el.getText();
    
        if (value != null && value.equals("joe.smith@acme.com")) {
          return true;
        } else {
          throw new LoginException("email value is bad");
        }
      }
      public boolean commit() throws LoginException {
        return true;
      }
      public boolean logout() throws LoginException {
        return false;
      }
      public boolean abort() throws LoginException {
        return false;
      }
    
    }
  3. Créez des configurations de connexion JAAS.
    1. Dans la console d'administration, sélectionnez Sécurité -> Sécurité globale.
    2. Sous Authentification, sélectionnez Service d'authentification et d'autorisation Java.
    3. Sélectionnez Connexions de système.
    4. Créez le générateur avec le module personnalisé préalablement.
      1. Cliquez sur Nouveau et définissez Alias = test.generate.custom.
      2. Cliquez sur Nouveau et définissez Module class name = test.tokens.MyCustomGenerator.
      3. Sélectionnez Utiliser le proxy de module de connexion .
      4. Cliquez sur OK.
      5. Cliquez sur Nouveau et sélectionnez Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenGenerateLoginModule.
      6. Cliquez sur OK.
      7. Cliquez sur JAAS - Connexions de système.
    5. Créez le consommateur avec module personnalisé en dernier.
      1. Cliquez sur Nouveau et définissez Alias = test.consume.custom.
      2. Cliquez sur Nouveau et sélectionnez Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenConsumeLoginModule.
      3. Cliquez sur Nouveau et définissez Module class name = test.tokens.MyCustomConsumer.
      4. Sélectionnez Utiliser le proxy de module de connexion.
      5. Cliquez sur OK.
    6. Cliquez sur Sauvegarder.
  4. Créez l'ensemble de règles personnalisé.
    1. Dans la console d'administration, cliquez sur Services > Ensembles de règles > Ensembles de règles d'application.
    2. Cliquez sur Nouveau et définissez ACustomTokenPolicy.
    3. Cliquez sur Appliquer.
    4. Dans Règles, cliquez sur Ajouter > WS-Security.
  5. Editez l'ensemble de règles personnalisé.
    1. Dans la console d'administration, cliquez sur WS-Security > Règle principale.
    2. Supprimez les éléments inutiles :
      1. Désélectionnez Inclure l'horodatage dans l'en-tête de sécurité.
      2. Désélectionnez Protection au niveau des messages.
    3. Ajoutez le jeton personnalisé.
      1. Cliquez sur Règles de jeton de demande
      2. Cliquez sur Ajouter un type de jeton > Personnalisé, puis spécifiez :
        • Custom token name = myToken
        • Local part = MyToken
        • Namespace URI = http://www.acme.com
      3. Cliquez sur OK.
    4. Cliquez sur Sauvegarder.
  6. Configurez le client pour utiliser l'ensemble de règles ACustomTokenPolicy.
    1. Dans la console d'administration, cliquez sur Services > Clients de service.
    2. Cliquez sur le client de service approprié.
    3. Sélectionnez la ressource dans le niveau supérieur.
    4. Cliquez sur Lier un ensemble de règles.
    5. Sélectionnez ACustomTokenPolicy.
  7. Créez une liaison personnalisée pour le client.
    1. Sélectionnez de nouveau la ressource dans le niveau supérieur.
    2. Cliquez sur Affecter une liaison.
    3. Cliquez sur Nouvelle liaison spécifique à l'application pour créer une liaison spécifique à l'application.
    4. Indiquez le nom de configuration des liaisons.

      name: customTokenClientBinding

    5. Cliquez sur Ajouter > WS-Security.

      Si le panneau Liaison de la règle de sécurité du message principal ne s'affiche pas, sélectionnez WS-Security.

  8. Configurez les liaisons personnalisées du client.
    1. Sélectionnez Authentification et protection > request:myToken.
    2. Sélectionnez JAAS login = test.generate.custom.
    3. Cliquez sur Appliquer.
    4. Cliquez sur Gestionnaire d'appel.
    5. Ajoutez la propriété personnalisée passThroughToken=true.
  9. Configurez le fournisseur pour utiliser l'ensemble de règles ACustomTokenPolicy.
    1. Dans la console d'administration, cliquez sur Services > Fournisseurs de services.
    2. Cliquez sur le fournisseur de service approprié.
    3. Sélectionnez la ressource dans le niveau supérieur.
    4. Cliquez sur Lier un ensemble de règles.
    5. Sélectionnez ACustomTok enPolicy.
  10. Créez une liaison personnalisée pour le fournisseur.
    1. Sélectionnez de nouveau la ressource dans le niveau supérieur.
    2. Cliquez sur Affecter une liaison.
    3. Cliquez sur Nouvelle liaison spécifique à l'application pour créer une liaison spécifique à l'application.
    4. Indiquez le nom de configuration des liaisons.

      customTokenProviderBinding

    5. Cliquez sur Ajouter > WS-Security.

      Si le panneau Liaison de la règle de sécurité du message principal ne s'affiche pas, sélectionnez WS-Security.

  11. Configurez les liaisons personnalisées du fournisseur.
    1. Sélectionnez Authentification et protection > request:myToken.
    2. Sélectionnez JAAS login = test.consume.custom.
    3. Cliquez sur Appliquer.
    4. Cliquez sur Gestionnaire d'appel.
    5. Ajoutez les propriétés personnalisées passThroughToken=true et alwaysGeneric=true.
  12. Cliquez sur Sauvegarder pour sauvegarder les modifications apportées à la configuration.
  13. Redémarrez le serveur d'applications pour appliquer les modifications à la configuration JAAS.
  14. Testez le service.

Exemple

L'exemple suivant montre l'en-tête de sécurité SOAP produit lorsque vous suivez la procédure précédente.

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
    <acme:MyToken xmlns:acme="http://www.acme.com" xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
        <acme:Email>joe.smith@acme.com</acme:Email>
    </acme:MyToken>
</wsse:Security>

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_gen_consum_custtokens
Nom du fichier : twbs_gen_consum_custtokens.html