— PEDRO DELGADO YARZA 2014/01/29 13:51
Es obligatorio realizar las modificaciones indicadas en la siguiente guía:
Actualización del Sistema de Autenticación de Aplicaciones FundeWeb
En Fundeweb 2.0 se ha dispuesto de un mecanismo de autenticación múltiple que dispone de una serie de métodos de autenticación implementados por defecto y nos permite añadir nuevos mecanismos para ampliar la funcionalidad del componente en caso de ser necesario. Los mecanismos existentes por defecto son los siguientes:
Este mecanismo se dispone en la clase AuthenticationManagerBean (que tiene que extender la clase AbstractAuthenticationManagerBean) en la cual según el método de autenticación que hayamos seleccionado, se lanzan las librerías necesarias para realizar la autenticación.
El siguiente código es el encargado de obtener la factoría de autenticación necesaria en cada caso.
protected AuthenticationFactory getFactoria(AuthenticationType authenticationType) { if (authenticationType == null) { activateCredentialsUmu( this.defaultAuthenticationType ); } switch (authenticationType) { case CARD: { return new AuthenticationFactoryCard(); } case CERTIFICATE: { return new AuthenticationFactoryCertificateSSL(); } case NIF: { return new AuthenticationFactoryNif(); } case RADIUS: { return new AuthenticationFactoryRadius(); } case SSO: { return new AuthenticationFactorySSO(); } default: { return this.defaultAuthenticationFactory; } } }
La estructura de una factoría consta de dos métodos:
El código de la factoría quedaría así:
public class AuthenticationFactoryRadius implements AuthenticationFactory { public AuthenticationMethod createAuthenticationMethod() { return new AuthenticationMethodRadius(); } public CredentialsUmu createCredentials() { return new CredentialsDefaultUmu(); } }
Si deseáramos ampliar la funcionalidad de Fundeweb 2.0 añadiendo un nuevo método de autenticación deberemos realizar lo siguiente:
public enum AuthenticationType { RADIUS, CARD, CERTIFICATE, NIF, SSO }
protected String getAuthenticationTypeLabel(AuthenticationType authenticationType) { ResourceBundle srb = SeamResourceBundle.getBundle(); try { switch (authenticationType) { case CARD: { return srb.getString("label.tipo_acceso_tarjeta"); } case CERTIFICATE: { return srb.getString("label.tipo_acceso_certificado"); } case NIF: { return srb.getString("label.tipo_acceso_nif"); } case RADIUS: { return srb.getString("label.tipo_acceso_correo"); } case SSO: { return srb.getString("label.tipo_acceso_sso"); } default: return this.defaultAuthenticationTypeLabel; } } catch (MissingResourceException mre) { LOG.error("Error al obtener las etiquetas para los tipos de autenticacion.", mre); } return ""; }
@Override public void preAuthenticate() { try { // Vuestro código para asignar los datos a la credencial getIdentity().getCredentials().setUsername("miusuario@um.es"); } catch (Throwable t) { LOG.error("Error inesperado.", t); } } @Override public boolean authenticate() { String usuario = getIdentity().getCredentials().getUsername(); LOG.info("Autenticando a: #0", usuario); if (!UtilString.esCadenaVacia(usuario) && !usuario.contains("@")) { usuario += "@um.es"; } if ("invitado@um.es".equals(usuario) && "bienvenido".equals(getIdentity().getCredentials().getPassword())) { return true; } try { ..... ..... ..... ..... } catch (ServiceNotFoundException snfe) { LOG.error("Error al buscar un servicio", snfe); } catch (PersonaException pe) { LOG.error("Error: al obtener los datos del Usuario en GENTE.", pe); processErrorMessage(); } catch (PersonaNotFoundException pnfe) { LOG.error("Error: el usuario no se encuentra en GENTE.", pnfe); processErrorMessage(); } return false; } @Override public void postAuthenticate() { try { // Vuestro código para realizar acciones después de la autenticación // y antes de lanzarse los eventos "org.jboss.seam.security.loginSuccessful" // o "org.jboss.seam.security.loginFailed" } catch (Throwable t) { LOG.error("Error inesperado.", t); } }
Tras estos pasos ya tendremos registrado y listo para usar nuestro nuevo mecanismo de autenticación.
También podemos extender o modificar algunos de los sistemas de autenticación ya creados.
Podemos personalizar los métodos de autenticación y las credenciales que estan disponibles por defecto en las aplicaciones FundeWeb.
En la factoria correspondiente al sistema de autenticación, aparecen las constantes para designar los nombres de el método de autenticación y la credencial. A continuación un ejemplo para personalizar el método de autenticación con NIF.
Podemos personalizar la autenticación con NIF (DNI/NIF/NIE) siguiendo los siguientes pasos:
Código de ejemplo:
package es.um.atica.prueba.security.authentication.method; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.intercept.BypassInterceptors; import org.jboss.seam.log.Log; import org.jboss.seam.log.Logging; import org.umu.atica.servicios.gesper.gente.exceptions.PersonaException; import org.umu.atica.servicios.gesper.gente.exceptions.PersonaNotFoundException; import buscador.servicios.exceptions.ServiceNotFoundException; import es.um.atica.seam.security.authentication.factories.AuthenticationFactoryNif; import es.um.atica.seam.security.authentication.method.AuthenticationMethod; @Name(AuthenticationFactoryNif.AUTHENTICATION_METHOD_NIF_COMPONENT_NAME) @BypassInterceptors public class PruebaAuthenticationMethodNif extends AuthenticationMethod { private static final Log LOG = Logging.getLog(PruebaAuthenticationMethodNif.class); @Override public boolean authenticate() { try { this.loadUser( getCredentials().getUsername() ); LOG.info("Autenticando a: #0 - #1", getCredentials().getUsername(), getUmuIdentity().getPersona().getCorreo()); // TODO logicapara la verificacion de las credenciales de autenticacion return ...; } catch (ServiceNotFoundException snfe) { LOG.error("Error al buscar un servicio", snfe); } catch (PersonaException pe) { LOG.error("Error: al obtener los datos del Usuario en GENTE.", pe); processErrorMessage(); } catch (PersonaNotFoundException pnfe) { LOG.error("Error: el usuario no se encuentra en GENTE.", pnfe); processErrorMessage(); } catch ( Throwable t ) { LOG.error("Error inesperado.", t); } return false; } @Override protected void loadUser(Object identifier) throws Exception { // TODO Cargar los datos del usuario (no permisos) // Este método carga los datos de la persona en base al DNI de Gente this.loadPersonaByIdentificador( (String) identifier ); } /* * (non-Javadoc) * @see es.um.atica.util.FundeWebManager#getLog() */ @Override protected Log getLog() { return LOG; } }
Para otros métodos de autenticación, hay que utilizar la factoria relacionada.