Para desarrollar un proveedor de autenticación JASPIC (Java™ Authentication
SPI for Containers) personalizado, cree clases que implementen las interfaces necesarias indicadas en la especificación
JSR 196: Java Authentication Service Provider Interface
for Containers.
Acerca de esta tarea
WebSphere Application Server Liberty Profile da soporte a la utilización de proveedores de autenticación de terceros que sean compatibles con el perfil de contenedor de servlet especificado en Java Authentication SPI for Containers (JASPIC) Versión 1.1.
El perfil de contenedor de servlet define las interfaces que utiliza el entorno de ejecución de seguridad en colaboración con el contenedor web en WebSphere Application Server para invocar los módulos de autenticación antes y después de que una aplicación procese una solicitud web. La autenticación que utiliza módulos JASPIC sólo se ejecuta cuando JASPIC está habilitado en la configuración de seguridad.
Para desarrollar un proveedor de autenticación personalizado, cree las clases que
implementan las interfaces necesarias indicadas en la especificación JSR 196:
Java
Authentication Service Provider Interface for Containers. Un proveedor puede utilizar uno o varios módulos de autenticación para la autenticación. Para realizar la autenticación, los módulos pueden utilizar la devolución de llamada o pueden añadir manualmente la información de identidad de usuario necesaria al asunto del cliente.
- Cree una clase que implemente la interfaz javax.security.auth.message.config.AuthConfigProvider.
La clase de implementación
AuthConfigProvider debe definir un constructor de dos argumentos público y el método público
getServerAuthConfig:
import java.util.Map;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.config.AuthConfigFactory;
import javax.security.auth.message.config.AuthConfigProvider;
import javax.security.auth.message.config.ServerAuthConfig;
public class SampleAuthConfigProvider implements AuthConfigProvider {
public SampleAuthConfigProvider(Map<String, String> properties, AuthConfigFactory factory) {
...
}
public ServerAuthConfig getServerAuthConfig(String layer, String appContext, CallbackHandler handler)
throws AuthException {
...
}
}
WebSphere Application Server utiliza una instancia de la clase de implementación AuthConfigProvider cuando llega una solicitud que ha de procesar el módulo web de la aplicación. El método getServerAuthConfig se utiliza para obtener una instancia de ServerAuthConfig. El módulo authentication utiliza el argumento CallbackHandler en la llamada de método.
- Cree una clase que implemente la interfaz javax.security.auth.message.config.ServerAuthConfig.
La clase de implementación
ServerAuthConfig debe definir los métodos públicos
getAuthContextID y
getAuthContext:
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.config.ServerAuthConfig;
import javax.security.auth.message.config.ServerAuthContext;
public class SampleServerAuthConfig implements ServerAuthConfig {
public String getAuthContextID(MessageInfo messageInfo) throws IllegalArgumentException {
...
}
public ServerAuthContext getAuthContext(String authContextID, Subject serviceSubject, Map properties)
throws AuthException {
...
}
}
Los métodos getAuthContextID y getAuthContext de la clase de implementación ServerAuthConfig se utilizan
para obtener una instancia de ServerAuthContext.
- Cree una clase que implemente la interfaz javax.security.auth.message.config.ServerAuthContext.
La clase de implementación
ServerAuthContext debe definir los métodos públicos
validateRequest y
secureResponse:
import javax.security.auth.Subject;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.config.ServerAuthContext;
public class SampleServerAuthContext implements ServerAuthContext {
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
throws AuthException {
...
}
public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject)
throws AuthException {
...
}
}
El método validateRequest de la clase de implementación ServerAuthContext se utiliza para invocar el
módulo que autentica el mensaje de solicitud web recibido.
Si el resultado de la autenticación es correcto, el contenedor web asigna
el mensaje de solicitud web recibido que el módulo web de destino procesa en la aplicación. Si el resultado de la autenticación no es correcto, la solicitud se rechaza con el estado de respuesta correspondiente.
- Cree una clase que implemente la interfaz javax.security.auth.message.module.ServerAuthModule.
La clase de implementación
ServerAuthModule debe definir los métodos públicos
initialize,
validateRequest y
secureResponse:
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import javax.security.auth.message.MessagePolicy;
import javax.security.auth.message.module.ServerAuthModule;
public class SampleAuthModule implements ServerAuthModule {
public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options)
throws AuthException {
...
}
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
throws AuthException {
...
}
public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject)
throws AuthException {
...
}
public void cleanSubject(MessageInfo messageInfo, Subject subject)
throws AuthException {
...
}
}
El método initialize de la clase de implementación
ServerAuthModule es invocado por la clase de implementación ServerAuthContext para inicializar el módulo authentication y asociarlo con la instancia de ServerAuthContext.
Los métodos
validateRequest y
secureResponse en esta clase se utilizan para autenticar las
javax.servlet.http.HttpServletRequest y
javax.servlet.http.HttpServletResponse contenidas en la
javax.security.auth.message.MessageInfo que se recibe. Estos métodos pueden utilizar la instancia de
CallbackHandler que se recibe en el método
initialize para interactuar con el tiempo de ejecución de seguridad de WebSphere para validar una contraseña de usuario, y el registro de usuarios activo para recuperar un ID exclusivo y grupos de pertenencia para un usuario. Los datos recuperados se colocan en una
Hashtable en el conjunto de credenciales privadas del asunto del
cliente. La implementación de WebSphere Application Server de
CallbackHandler da soporte a las tres devoluciones de llamada siguientes:
- • CallerPrincipalCallback
- • GroupPrincipalCallback
- • PasswordValidationCallback
WebSphere Application Server espera que los valores de nombres obtenidos con PasswordValidationCallback.getUsername() y CallerPrincipalCallback.getName() sean idénticos. Si no lo
son, se producen resultados inesperados. El método handle() de CallbackHandler procesa cada devolución de llamada que se proporciona en la matriz de argumentos del método de forma secuencial. Por consiguiente, el valor de nombre establecido en las credenciales privadas del asunto de cliente es el que se ha obtenido en la última devolución de llamada procesada.
Si el módulo de autenticación no utiliza CallbackHandler y validateRequest devuelve un estado de
satisfactorio, WebSphere Application Server requiere que se incluya una instancia de
Hashtable en el
clientSubject con información de identidad de usuario para que se puede realizar un inicio de sesión personalizado obtener las credenciales para el usuario. Esta
Hashtable se puede añadir al sujeto del cliente, como en el ejemplo siguiente:
import java.util.Hashtable;
import java.util.String;
import javax.security.auth.Subject;
import javax.security.auth.message.AuthException;
import javax.security.auth.message.AuthStatus;
import javax.security.auth.message.MessageInfo;
import com.ibm.wsspi.security.registry.RegistryHelper;
import com.ibm.wsspi.security.token.AttributeNameConstants.AttributeNameConstants;
public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject)
throws AuthException {
...
UserRegistry reg = RegistryHelper.getUserRegistry(null);
String uniqueid = reg.getUniqueUserID(username);
Hashtable hashtable = new Hashtable();
hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueid);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_PASSWORD, password);
hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groupList); //optional
clientSubject.getPrivateCredentials().add(hashtable);
...
}
Para obtener más información sobre los requisitos de Hashtable y el inicio de sesión personalizado, consulte Desarrollo de módulos de inicio de sesión personalizados JAAS para una configuración de inicio de sesión en el sistema.