Sustitución del método de autenticación del consumidor UsernameToken utilizando un módulo de inicio de sesión JAAS apilado

De forma predeterminada, el consumidor UsernameToken de seguridad de servicios web, UNTConsumeLoginModule, siempre valida el nombre de usuario y la contraseña que se encuentran dentro de la señal en el registro de WebSphere. Puede utilizar las SPI que GenericSecurityTokenFactory proporciona para eludir este método de autenticación.

Acerca de esta tarea

Si desea sustituir el método de autenticación que utiliza UNTConsumeLoginModule, debe proporcionar su propio módulo de inicio de sesión JAAS personalizado para realizar la autenticación. El módulo de inicio de sesión personalizado se apila en UNTConsumeLoginModule en una configuración de JAAS personalizada. El UNTConsumeLoginModule consume y valida la señal XML. La validación de los valores proporcionados para el nombre de usuario y la contraseña se aplaza para el módulo de inicio de sesión personalizado apilado.

Debido a que el uso de UNTConsumeLoginModule lleva consigo la suposición de que el nombre de usuario y la contraseña serán autenticados, se colocan más requisitos en un módulo de inicio de sesión apilado que tiene la intención de realizar esta función que los que se colocan en los módulos de inicio de sesión para proporcionar funciones de señal dinámica.

Para indicar a UNTConsumeLoginModule que no debe autenticar el nombre de usuario y la contraseña, debe establecer la propiedad siguiente en el manejador de retorno de llamada configurado:

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

Al igual que la mayoría de los módulos de inicio de sesión WS-Security, UNTConsumeLoginModule siempre coloca la señal consumida en la correlación de estado compartido a la que tienen acceso todos los módulos de inicio de sesión de la pila. Cuando se especifica authDeferred=true, en la fase de confirmación, UNTConsumeLoginModule asegura que el mismo objeto UsernameToken que había sido puesto en el estado compartido ha sido puesto en otra ubicación en el estado compartido. Si este objeto UsernameToken no se puede encontrar, se produce una excepción LoginException. Por lo tanto, simplemente no se puede establecer authDeferred=true en el manejador de devolución de llamada sin hacer que un módulo de inicio de sesión que acompaña devuelva la señal al estado compartido.

Procedimiento

  1. Desarrolle un módulo de inicio de sesión JAAS para realizar la autenticación y póngalo a disposición del código de aplicación. Este nuevo módulo de inicio de sesión se apila en com.ibm.ws.wssecurity.wssapi.token.impl.UNTConsumeLoginModule.

    Este módulo de inicio de sesión debe:

    1. Utilizar el método siguiente para obtener el UsernameToken que UNTConsumeLoginModule consume.
      UsernameToken unt = (UsernameToken)factory.getConsumerTokenFromSharedState(sharedState,UsernameToken.ValueType);
      En este ejemplo de código, la fábrica es una instancia de com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory.
    2. Compruebe el nombre de usuario y la contraseña en la forma que elija.

      Puede llamar a unt.getUsername() y unt.getPassword() para obtener el nombre de usuario y la contraseña.

      El módulo de inicio de sesión debería lanzar una LoginException si existe un error de autenticación.

    3. Coloque el UsernameToken, que se ha obtenido en el subpaso anterior, en el estado compartido.

      Utilice el método siguiente para poner el UsernameToken en el estado compartido.

      factory.putAuthenticatedTokenToSharedState(sharedState, unt);

    A continuación se muestra un módulo de inicio de sesión de ejemplo :

    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 {
        //Para facilitar la comprensión, este módulo de inicio de sesión no
        //protege contra todos los NPE
    
        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();
    
        //autenticar el nombre de usuario y la contraseña
        //para validar una contraseña PasswordDigest
        //String pw = yourCodeToLookUpPasswordForUsername(username);
        //boolean match = utilFactory.verifyDigestedPassword(unt, pw.toCharArray());
        //if (!match) throw new LoginException("Digested passwords do not match");
        //Ejemplo:
                 try {
          simpleUserGroupCheck(username, password, "cn=group1,o=ibm,c=us");
        } catch(Exception e) {
          LoginException le = new LoginException(e.getMessage());
          le.initCause(e);
          throw le;
        }
    
        //Coloque la señal autenticada en el estado compartido
        factory.putAuthenticatedTokenToSharedState(this._sharedState, unt);
    
        return true;
      }
    
      private boolean simpleUserGroupCheck(String username, char [] password, String group) throws Exception {
        String allowedGroup = null;
    
        	  //obtener el registro de usuario predeterminado
        UserRegistry user_reg = RegistryHelper.getUserRegistry(null);
    
        //autenticar el usuario con el registro de usuarios
        user_reg.checkPassword(username, new String(password));
    
        //obtener la lista de grupos a los que pertenece el usuario
        java.util.List<String> groupList = user_reg.getGroupsForUser(username);
    
        //puede utilizar un grupo codificado
        allowedGroup = group;
    
        //u obtener el valor de su propia propiedad personalizada en el manejador de devolución de llamada
        //WSSUtilFactory util = WSSUtilFactory.getInstance();
        //Map map = util.getCallbackHandlerProperties(this._handler);
        //allowedGroup = (String) map.get("MY_ALLOWED_GROUP_1");
    
        //comprobar si el usuario pertenece a un grupo permitido
        if (!groupList.contains(allowedGroup)) {
          throw new LoginException("user ["+username+"] is not in allowed group ["+allowedGroup+"]");
        }
        return true;
    }
      //implemente el resto de métodos requeridos por la
      //interfaz de módulo de inicio de sesión
    }
  2. Cree una nueva configuración de inicio de sesión JAAS.
    1. En la consola administrativa, pulse Seguridad > Seguridad global.
    2. En Autenticación, seleccione Servicio de autenticación y autorización Java.
    3. Seleccione Inicios de sesión de sistema.
    4. Pulse Nuevo y, a continuación, especifique Alias = test.consume.unt.
    5. Pulse Nuevo y, a continuación, seleccione Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.UNTConsumeLoginModule.
    6. Pulse Nuevo y luego especifique Module class name = test.tokens.MyUntAuthenticator.
    7. Seleccione Utilizar proxy de módulo de inicio de sesión .
    8. Pulse Aceptar y, a continuación, pulse Guardar.
  3. Configure el consumidor de señal de UsernameToken para utilizar la nueva configuración JAAS.
    1. Abra la configuración de enlaces que desea cambiar.

      En la consola administrativa, seleccione WS-Security > Autenticación y protección.

    2. En Señales de autenticación, seleccione la señal de entrada UsernameToken que desea cambiar.
    3. Seleccione JAAS login = test.consume.unt.
  4. Establezca la propiedad necesaria en el manejador de devolución de llamada que se configura para el consumidor UsernameToken.
    1. Pulse Manejador de retorno de llamada.
    2. Añada la propiedad personalizada com.ibm.wsspi.wssecurity.token.UsernameToken.authDeferred=true .
    3. Pulse OK (Aceptar).
  5. Pulse SAVE.
  6. Reinicie el servidor de aplicaciones para aplicar los cambios de configuración JAAS.
  7. Pruebe el servicio.

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_replace_authmethod_usernametoken
File name: twbs_replace_authmethod_usernametoken.html