Remplacement de la méthode d'authentification du consommateur de jeton UsernameToken à l'aide d'un module de connexion JAAS empilé

Par défaut, le consommateur de jeton UsernameToken de la sécurité des services Web, le module UNTConsumeLoginModule, valide toujours le nom d'utilisateur et le mot de passe contenus dans le jeton par rapport au registre WebSphere. Vous pouvez utiliser les SPI fournies par GenericSecurityTokenFactory pour ignorer cette méthode d'authentification.

Pourquoi et quand exécuter cette tâche

Si vous souhaitez remplacer la méthode d'authentification utilisée par le module UNTConsumeLoginModule, vous devez fournir votre propre module de connexion JAAS personnalisé pour procéder à l'authentification. Le module de connexion personnalisé est empilé sous le module UNTConsumeLoginModule dans une configuration JAAS personnalisée. Le module UNTConsumeLoginModule consomme et valide le XML du jeton. La validation des valeurs fournies pour le nom d'utilisateur et le mot de passe est reportée dans le module de connexion empilé personnalisé.

L'utilisation du module UNTConsumeLoginModule signifiant que le nom d'utilisateur et le mot de passe seront authentifiés, davantage d'exigences sont placées sur un module de connexion empilé qui a l'intention d'effectuer cette fonction que sur des modules de connexion destinés à n'offrir qu'une fonctionnalité de jeton dynamique.

Pour indiquer au module UNTConsumeLoginModule qu'il ne doit pas authentifier le nom d'utilisateur et le mot de passe, vous devez définir la propriété suivante sur le gestionnaire de rappel configuré :

com.ibm.wsspi.wssecurity.token.UsernameToken.authDeferred=true

Comme la plupart des modules de connexion WS-Security, le module UNTConsumeLoginModule place toujours le jeton consommé dans la mappe des états partagés à laquelle tous les modules de connexion de la pile ont accès. Si authDeferred=true est spécifié, dans la phase de validation, le module UNTConsumeLoginModule s'assure que l'objet UsernameToken placé à l'origine à l'état partagé a été placé dans un autre emplacement à l'état partagé. Si cet objet UsernameToken est introuvable, une exception LoginException se produit. Par conséquent, vous ne pouvez pas seulement spécifier authDeferred=true sur le gestionnaire de rappel sans qu'un module de connexion associé ne retourne le jeton à l'état partagé.

Procédure

  1. Développez un module de connexion JAAS pour effectuer l'authentification et rendez-le accessible au code d'application. Ce nouveau module de connexion est empilé sous com.ibm.ws.wssecurity.wssapi.token.impl.UNTConsumeLoginModule.

    Ce module de connexion doit :

    1. Utiliser la méthode ci-après pour extraire le jeton UsernameToken consommé par le module UNTConsumeLoginModule.
      UsernameToken unt = (UsernameToken)factory.getConsumerTokenFromSharedState(sharedState,UsernameToken.ValueType);
      Dans cet exemple de code, factory est une instance de com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory.
    2. Vérifier le nom d'utilisateur et le mot de passe suivant la manière de votre choix.

      Vous pouvez appeler unt.getUsername() et unt.getPassword() pour extraire le nom d'utilisateur et le mot de passe.

      Votre module de connexion doit générer une exception LoginException en cas d'erreur d'authentification.

    3. Replacer le jeton UsernameToken, obtenu lors de la sous-étape précédente, à l'état partagé.

      Utilisez la méthode ci-après pour replacer le jeton UsernameToken à l'état partagé.

      factory.putAuthenticatedTokenToSharedState(sharedState, unt);

    Voici un exemple de module de connexion :

    package test.tokens;
    
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
    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 com.ibm.websphere.wssecurity.wssapi.token.UsernameToken;
    
    import java.util.ArrayList;
    
    import com.ibm.wsspi.security.registry.RegistryHelper;
    import com.ibm.websphere.security.UserRegistry;
    
    public class MyUntAuthenticator 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 {
        //For the sake of readability, this login module does not
        //protect against all NPE's
    
        GenericSecurityTokenFactory factory = null;
        WSSUtilFactory utilFactory = null;
        try {
          factory = GenericSecurityTokenFactory.getInstance();
          utilFactory = WSSUtilFactory.getInstance();
        } catch (Exception e) {
          throw new LoginException(e.toString());
        }
        if (factory == null) {
          throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null");
        }
    
        UsernameToken unt = (UsernameToken)factory.getConsumerTokenFromSharedState(this._sharedState,UsernameToken.ValueType);
    
        String username = unt.getUsername();
        char [] password = unt.getPassword();
    
        //authenticate the username and password 
        //to validate a PasswordDigest password 
        //String pw = yourCodeToLookUpPasswordForUsername(username);
        //boolean match = utilFactory.verifyDigestedPassword(unt, pw.toCharArray());
        //if (!match) throw new LoginException("Digested passwords do not match");
        //Example:
        try {
          simpleUserGroupCheck(username, password, "cn=group1,o=ibm,c=us");
        } catch (Exception e) {
          LoginException le = new LoginException(e.getMessage());
          le.initCause(e);
          throw le;
        }
    
        //Put the authenticated token to the shared state
        factory.putAuthenticatedTokenToSharedState(this._sharedState, unt);
    
        return true;
      }
    
      private boolean simpleUserGroupCheck(String username, char [] password, String group) throws Exception {
        String allowedGroup = null;
    
        //get the default user registry
        UserRegistry user_reg = RegistryHelper.getUserRegistry(null);
    
        //authenticate the user against the user registry
        user_reg.checkPassword(username, new String(password));
    
        //get the list of groups that the user belongs to
        java.util.List<String> groupList = user_reg.getGroupsForUser(username);
    
        //you can either use a hard-coded group
        allowedGroup = group;
    
        //or get the value from your own custom property on the callback handler
        //WSSUtilFactory util = WSSUtilFactory.getInstance();
        //Map map = util.getCallbackHandlerProperties(this._handler);
        //allowedGroup = (String) map.get("MY_ALLOWED_GROUP_1");
    
        //check if the user belongs to an allowed group
        if (!groupList.contains(allowedGroup)) {
          throw new LoginException("user ["+username+"] is not in allowed group ["+allowedGroup+"]");
        }
        return true;
    }
      //implement the rest of the methods required by the
      //LoginModule interface
    }
  2. Créez une configuration 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. Cliquez sur Nouveau et définissez Alias = test.consume.unt.
    5. Cliquez sur Nouveau et sélectionnez Nom de la classe du module = com.ibm.ws.wssecurity.wssapi.token.impl.UNTConsumeLoginModule
    6. Cliquez sur Nouveau et spécifiez Nom de la classe du module = test.tokens.MyUntAuthenticator
    7. Sélectionnez Utiliser le proxy de module de connexion.
    8. Cliquez sur OK, puis sur Sauvegarder.
  3. Configurez votre consommateur de jeton UsernameToken pour qu'il utilise la nouvelle configuration JAAS.
    1. Ouvrez votre configuration de liaisons à modifier.

      Dans la console d'administration, sélectionnez WS-Security > Authentification et protection.

    2. Sous Jetons d'authentification, sélectionnez le jeton UsernameToken entrant à modifier.
    3. Sélectionnez JAAS login = test.consume.unt.
  4. Définissez la propriété requise sur le gestionnaire de rappel configuré pour le consommateur de jeton UsernameToken.
    1. Cliquez sur Gestionnaire d'appel.
    2. Ajoutez la propriété personnalisée com.ibm.wsspi.wssecurity.token.UsernameToken.authDeferred=true.
    3. Cliquez sur OK.
  5. Cliquez sur Sauvegarder.
  6. Redémarrez le serveur d'applications pour appliquer les modifications à la configuration JAAS.
  7. Testez le service.

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_replace_authmethod_usernametoken
Nom du fichier : twbs_replace_authmethod_usernametoken.html