Versiones comparadas

Clave

  • Se ha añadido esta línea.
  • Se ha eliminado esta línea.
  • El formato se ha cambiado.

...

Hay que modificar o añadir las siguientes carpetas y ficheros:

...

AuthenticationManagerBean.java

...

  • Modificar esta clase haciendo que extienda a AbstractAuthenticationManagerBean en lugar de a FundeWebManagerBean (línea 37).
  • Modificar el enumerado AuthenticationType (línea 54) y añadir el método get getAuthenticationTypes (línea 89).


Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

public class AuthenticationMethodNotSupportedException extends RuntimeException {

	private static final long serialVersionUID = -7140000370097499128L;

	private static final String MENSAJE = "No se soporta el método de autenticación: ";

	public AuthenticationMethodNotSupportedException( String message ) {
		super( MENSAJE + message );
	}

	public AuthenticationMethodNotSupportedException( Throwable cause ) {
		super( MENSAJE, cause );
	}

	public AuthenticationMethodNotSupportedException( String message, Throwable cause ) {
		super( MENSAJE + message, cause );
	}
}

AuthenticationMethodSSO.java

Añadir esta clase que es idéntica a es.um.atica.seam.security.authentication.method.AuthenticationMethodSSO.java salvo porque sobrescribe al final el método preAuthenticate() (línea 96):

Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Objects;
import static org.jboss.seam.ScopeType.SESSION;
import static org.jboss.seam.annotations.Install.FRAMEWORK;

import java.io.Serializable;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.faces.model.SelectItem;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.SeamResourceBundle;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;

import org.jboss.seam.util.Strings;
import org.umues.um.atica.serviciosapium.gespersecurity.genteauthentication.entityws.PersonaAuthenticationFactoryCorreo;
import orges.umuum.atica.serviciosseam.gesper.gente.exceptions.PersonaExceptionsecurity.CredentialsAdapter;
import orges.umuum.atica.serviciosseam.gesper.gente.exceptions.PersonaNotFoundException;
security.UmuIdentity;
import buscador.servicios.exceptions.ServiceNotFoundException;
import es.um.atica.apiumseam.security.authentication.AuthenticationManagerBean.AuthenticationTypeAbstractAuthenticationManagerBean;
import es.um.atica.seam.security.authentication.methodcredentials.AuthenticationMethodCredentialsUmu;
import es.um.atica.seam.utils.CasClient3Util;

/**
 * Clase para definir el metodo de autenticación por SSO mediante CAS de la UMU.
 * 
 * @author juanmiguelbg
 * @version 0.0.3
 */
public class AuthenticationMethodSSO extends AuthenticationMethod {
security.authentication.factories.AuthenticationFactory;
import es.um.atica.seam.security.authentication.method.AuthenticationMethod;

@Name( "authenticationManagerBean" )
@Scope( SESSION )
@Install( precedence = FRAMEWORK )
@BypassInterceptors
@Startup
public class AuthenticationManagerBean extends AbstractAuthenticationManagerBean implements Serializable {

	/**
	 * serialVersionUID generado automaticamente
	 */
	private static final long serialVersionUID = -6064182119922723132L;

	/** Logger de la clase */
	private static final Log LOG = Logging.getLog(AuthenticationMethodSSO AuthenticationManagerBean.class );

	protected SelectItem[] selectItemsAutentication;

	/** Credencial private static final String CLIENT_NAME_KEY = "clientName";
    private static final String AUTHENTICATION_METHOD_NAME_KEY = "authenticationMethod";
    private static final String CLAVE_CLIENT_NAME = "Cl@ve";
    private static final String CERT_CLIENT_NAME = "Cert";
    private static final String FIRST_NAME_KEY = "FirstName";
    private static final String FAMILY_NAME_KEY = "FamilyName";
    
   /*
     * (non-Javadoc)
     * 
     * @see es.um.atica.util.FundeWebManager#getLog()
     */
    @Override
    protected Log getLog() {
        return LOG;
    }
    
    @Override
	public boolean authenticate() {
		LOG.info("Autenticando a: #0", getCredentials().getUsername());
		getStatusMessages().clearGlobalMessages();
		try {
            if ( isDni( getCredentials().getUsername() ) ) { // Autenticacion Clave - DNI
                loadPersonaByDniCAS( getCredentials().getUsername() );
            } else { // Autenticacion Correo UMU - Ticarum
                loadUser( getCredentials().getUsername() );
            }
			return true;
		} catch (ServiceNotFoundException snfe) {
			LOG.error("Error al buscar el servicio de Gente", 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;
	}

    private void loadPersonaByDniCAS( String username )
            throws PersonaException, PersonaNotFoundException, ServiceNotFoundException {
        try {
            loadPersonaByIdentificador( username );
        } catch ( PersonaNotFoundException pnfe ) {
            LOG.warn( "El usuario no se encuentra en GENTE, completamos con datos del CAS.", pnfe );
actual */
	protected CredentialsAdapter credentialsAdapter;

	protected AuthenticationType authenticationType;

	public enum AuthenticationType {
		CORREO( null, null, "label.tipo_acceso_correo" ),
		SSO( "LdapAuthenticationHandler", null, "label.authentication.type.correoum" ),
		SSO_CLAVE( "ClientAuthenticationHandler", "Cl@ve", "label.authentication.type.clave" ),
		// SSO_CMN( "ClientAuthenticationHandler", "CMN", "label.authentication.type.cmn" ),
		SSO_CERT( "ClientAuthenticationHandler", "Cert", "label.authentication.type.cert" );

		private String authenticationMethod;
		private String clientName;
		private String descKey;

		AuthenticationType( String authenticationMethod, String clientName ) {
			this.authenticationMethod = authenticationMethod;
			this.clientName = clientName;
		}

		AuthenticationType( String authenticationMethod, String clientName, String descKey ) {
			this( authenticationMethod, clientName );
			this.descKey = descKey;
		}

		public String getAuthenticationMethod() {
			return authenticationMethod;
		}

		public String getClientName() {
			return clientName;
		}

		public String getDescKey() {
			return descKey;
		}

	}

	public AuthenticationType[] getAuthenticationTypes() {
		return AuthenticationType.values();
	}

	private static final String ERROR_FIRMA = "0";

	public AuthenticationManagerBean() { // Por defecto CORREO
		this.credentialsAdapter = ( CredentialsAdapter ) this.getCredentials();
		this.authenticationType = AuthenticationType.CORREO;
		this.activateCredentialsUmu();
		int idx = 0;
		selectItemsAutentication = new SelectItem[AuthenticationType.values().length];
		for ( AuthenticationType type : AuthenticationType.values() ) {
			selectItemsAutentication[idx++] = new SelectItem( type.name(), getAuthenticationTypeLabel( type ) );
		}
	}

	public void activateCredentialsUmu() {
		LOG.info( "Entrar en activateCredentialsUmu: #0", this.authenticationType.name() );
		this.credentialsAdapter.setCredentialsUmu( getFactoria( this.authenticationType ).createCredentials() );
	}

	/**
	 * Metodo para activar una credencial.<br />
	 * Si la que se desea activar, es la que est� actualmente, no se hace nada y se devuelve false. En otro caso se
	 * devolver� true.
	 * 
	 * @param credencial
	 *                   Clase de Credencial a activar.
	 * @return Si => se creo una nueva credencial. No => ya estaba esa misma credencial activa.
	 */
	public boolean activateCredentialsUmu( AuthenticationType authenticationType ) {
		LOG.info( "Entrar en activateCredentialsUmu: #0",
				( authenticationType != null ? authenticationType.name() : "" ) );
		if ( ( this.getCredentialsUmu() != null ) && ( this.authenticationType == authenticationType ) ) {
			if ( LOG.isDebugEnabled() ) {
				LOG.debug( "La credencial actual y la pedida son iguales, luego no se crear� una nueva: #0.",
						this.authenticationType );
			}
			return false;
		}
		if ( authenticationType != null ) {
			this.setAuthenticationType( authenticationType );
		} else { // Por defecto CORREO
			this.setAuthenticationType( AuthenticationType.CORREO );
		}
		this.credentialsAdapter.setCredentialsUmu( getFactoria( this.authenticationType ).createCredentials() );
		return true;
	}

	public AuthenticationMethod getAuthenticationMethod() {
		return this.getFactoria( this.authenticationType ).createAuthenticationMethod();
	}

	/**
	 * @param authenticationType
	 *                      loadPersonaByDniClave( username );
   - parametro de Seam por }defecto
	 *   }

    private void loadPersonaByDniClave( String username@return
	 */
	protected AuthenticationFactory getFactoria( AuthenticationType authenticationType ) {
		if ( this.authenticationType == null    Map<String, Object> atributos = CasClient3Util.getPrincipalAttributes( CasClient3Util.getCasClient3Principal()) {
			activateCredentialsUmu( AuthenticationType.CORREO );
		}
		switch (  this.authenticationType )    LOG.info( "Atributos: #0", atributos );
        String client = (String) atributos.get( CLIENT_NAME_KEY );
        if ( !Strings.isEmpty( client )
                && ( CLAVE_CLIENT_NAME.equals( client ) || CERT_CLIENT_NAME.equals( client ) ) ) {
            String nombre = new String( ( ( String ) atributos.get( FIRST_NAME_KEY ) ).getBytes(), StandardCharsets.UTF_8 );
            String apellidos = new String( ( ( String ) atributos.get( FAMILY_NAME_KEY ) ).getBytes(),
                    StandardCharsets.UTF_8 );
            Persona persona = new Persona( username, nombre, apellidos, null );
            getUmuIdentity().setPersona( persona );
        }
    }
    
    @Override
	public void preAuthenticate() {
		final Map<String, Object> atributos = CasClient3Util.getPrincipalAttributes( CasClient3Util.getCasClient3Principal() );
		final String credentialType = ( String ) atributos.get( AUTHENTICATION_METHOD_NAME_KEY );
		final String client = ( String ) atributos.get( CLIENT_NAME_KEY );

		boolean encontrado = false;
		for ( final AuthenticationType authType : AuthenticationType.values() ) {
			if ( Objects.equals( credentialType, authType.getAuthenticationMethod() )
					&& Objects.equals( client, authType.getClientName() ) ) {
				encontrado = true;
				break;
			}
		}
		if ( !encontrado ) {
			throw new AuthenticationMethodNotSupportedException( client );
		}
	}
}

AuthenticationFactorySSO.java

Añadir esta clase asegurándonos que en el return del método createAuthenticationMethod() ponemos el nombre completo de la clase anterior (línea 11):

Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

import es.um.atica.seam.security.authentication.credentials.CredentialsDefaultUmu;
import es.um.atica.seam.security.authentication.credentials.CredentialsUmu;
import es.um.atica.seam.security.authentication.factories.AuthenticationFactory;
import es.um.atica.seam.security.authentication.method.AuthenticationMethod;

public class AuthenticationFactorySSO implements AuthenticationFactory {

	public AuthenticationMethod createAuthenticationMethod() {
		return new es.um.atica.apium.security.authentication.AuthenticationMethodSSO();
	}

	public CredentialsUmu createCredentials() {
		return new CredentialsDefaultUmu();
	}
}

AuthenticationManagerBean.java

  • Modificar esta clase haciendo que extienda a AbstractAuthenticationManagerBean en lugar de a FundeWebManagerBean (línea 37).
  • Modificar el enumerado AuthenticationType (línea 54) y añadir el método get getAuthenticationTypes (línea 89).
  • Modificar los métodos getFactoria (línea 148) y getAuthenticationTypeLabel (línea 165) y nos asegurarnos que el return del método getFactoria() en el caso SSO ponemos el nombre completo de la clase anterior (línea 157).
Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

import static org.jboss.seam.ScopeType.SESSION;
import static org.jboss.seam.annotations.Install.FRAMEWORK;

import java.io.Serializable;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.faces.model.SelectItem;

import org.jboss.seam.Component;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.core.SeamResourceBundle;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;

import es.um.atica.apium.security.authentication.ws.AuthenticationFactoryCorreo;
import es.um.atica.seam.security.CredentialsAdapter;
import es.um.atica.seam.security.UmuIdentity;
import es.um.atica.seam.security.authentication.AbstractAuthenticationManagerBean;
import es.um.atica.seam.security.authentication.credentials.CredentialsUmu;
import es.um.atica.seam.security.authentication.factories.AuthenticationFactory;
import es.um.atica.seam.security.authentication.method.AuthenticationMethod;

@Name( "authenticationManagerBean" )
@Scope( SESSION )
@Install( precedence = FRAMEWORK )
@BypassInterceptors
@Startup
public class AuthenticationManagerBean extends AbstractAuthenticationManagerBean implements Serializable {

	/**
	 * serialVersionUID generado automaticamente
	 */
	private static final long serialVersionUID = -6064182119922723132L;

	/** Logger de la clase */
	private static final Log LOG = Logging.getLog( AuthenticationManagerBean.class );

	protected SelectItem[] selectItemsAutentication;

	/** Credencial actual */
	protected CredentialsAdapter credentialsAdapter;

	protected AuthenticationType authenticationType;

	public enum AuthenticationType {
		CORREO( null, null, "label.tipo_acceso_correo" ),
		SSO( "LdapAuthenticationHandler", null, "label.authentication.type.correoum" ),
		SSO_CLAVE( "ClientAuthenticationHandler", "Cl@ve", "label.authentication.type.clave" ),
		// SSO_CMN( "ClientAuthenticationHandler", "CMN", "label.authentication.type.cmn" ),
		SSO_CERT( "ClientAuthenticationHandler", "Cert", "label.authentication.type.cert" );

		private String authenticationMethod;
		private String clientName;
		private String descKey;

		AuthenticationType( String authenticationMethod, String clientName ) {
			this.authenticationMethod = authenticationMethod;
			this.clientName = clientName;
		}

		AuthenticationType( String authenticationMethod, String clientName, String descKey ) {
			this( authenticationMethod, clientName );
			this.descKey = descKey;
		}

		public String getAuthenticationMethod() {
			return authenticationMethod;
		}

		public String getClientName() {
			return clientName;
		}

		public String getDescKey() {
			return descKey;
		}

	}

	public AuthenticationType[] getAuthenticationTypes() {
		return AuthenticationType.values();
	}

	private static final String ERROR_FIRMA = "0";

	public AuthenticationManagerBean() { // Por defecto CORREO
		this.credentialsAdapter = ( CredentialsAdapter ) this.getCredentials();
		this.authenticationType = AuthenticationType.CORREO;
		this.activateCredentialsUmu();
		int idx = 0;
		selectItemsAutentication = new SelectItem[AuthenticationType.values().length];
		for ( AuthenticationType type : AuthenticationType.values() ) {
			selectItemsAutentication[idx++] = new SelectItem( type.name(), getAuthenticationTypeLabel( type ) );
		}
	}

	public void activateCredentialsUmu() {
		LOG.info( "Entrar en activateCredentialsUmu: #0", this.authenticationType.name() );
		this.credentialsAdapter.setCredentialsUmu( getFactoria( this.authenticationType ).createCredentials() );
	}

	/**
	 * Metodo para activar una credencial.<br />
	 * Si la que se desea activar, es la que est� actualmente, no se hace nada y se devuelve false. En otro caso se
	 * devolver� true.
	 * 
	 * @param credencial
	 *                   Clase de Credencial a activar.
	 * @return Si => se creo una nueva credencial. No => ya estaba esa misma credencial activa.
	 */
	public boolean activateCredentialsUmu( AuthenticationType authenticationType ) {
		LOG.info( "Entrar en activateCredentialsUmu: #0",
				( authenticationType != null ? authenticationType.name() : "" ) );
		if ( ( this.getCredentialsUmu() != null ) && ( this.authenticationType == authenticationType ) ) {
			if ( LOG.isDebugEnabled() ) {
				LOG.debug( "La credencial actual y la pedida son iguales, luego no se crear� una nueva: #0.",
						this.authenticationType );
			}
			return false;
		}
		if ( authenticationType != null ) {
			this.setAuthenticationType( authenticationType );
		} else { // Por defecto CORREO
			this.setAuthenticationType( AuthenticationType.CORREO );
		}
		this.credentialsAdapter.setCredentialsUmu( getFactoria( this.authenticationType ).createCredentials() );
		return true;
	}

	public AuthenticationMethod getAuthenticationMethod() {
		return this.getFactoria( this.authenticationType ).createAuthenticationMethod();
	}

	/**
	 * @param authenticationType
	 *                           - parametro de Seam por defecto
	 * @return
	 */
	protected AuthenticationFactory getFactoria( AuthenticationType authenticationType ) {
		if ( this.authenticationType == null ) {
			activateCredentialsUmu( AuthenticationType.CORREO );
		}
		switch ( this.authenticationType ) {
			case SSO: // case SSO
			case SSO_CLAVE:
			//case SSO_CMN:
			case SSO_CERT:
				return new es.um.atica.apium.security.authentication.AuthenticationFactorySSO();
			case CORREO: // case CORREO
				return new AuthenticationFactoryCorreo();
			default:
				return new es.um.atica.apium.security.authentication.AuthenticationFactoryRadius();
		}
	}

	protected String getAuthenticationTypeLabel( AuthenticationType authenticationType ) {
		ResourceBundle srb = SeamResourceBundle.getBundle();

		try {
			return srb.getString( authenticationType.getDescKey() );
		} catch ( MissingResourceException mre ) {
			LOG.error( "Error al obtener las etiquetas para los tipos de autenticacion.", mre );
		}
		return "";
	}

	/**
	 * Obtiene la credencial actual.
	 */
	public CredentialsUmu getCredentialsUmu() {
		return this.credentialsAdapter.getCredentialsUmu();
	}

	public AuthenticationType getAuthenticationType() {
		return authenticationType;
	}

	public void setAuthenticationType( AuthenticationType authenticationType ) {
		LOG.debug( "Entra en setAuthenticationType: #0 - #1", authenticationType.hashCode(),
				authenticationType.name() );
		this.authenticationType = authenticationType;
	}

	public boolean isCorreoAuthentication() {
		return this.authenticationType == AuthenticationType.CORREO;
	}

	public boolean isSsoAuthentication() {
		return this.authenticationType == AuthenticationType.SSO;
	}

	public SelectItem[] getSelectItemsAutentication() {
		return selectItemsAutentication;
	}

	@Observer( UmuIdentity.EVENT_AUTHENTICATING_BY_CAS )
	public void activarAuthenticacionSSO() {
		LOG.debug( "Entra en activarAuthenticacionSSO" );
		this.authenticationType = AuthenticationType.SSO;
		this.activateCredentialsUmu();
	}

	/*
	 * (non-Javadoc)
	 * @see es.um.atica.util.FundeWebManager#getLog()
	 */
	@Override
	protected Log getLog() {
		return LOG;
	}

	public static AuthenticationManagerBean instance() {
		if ( !Contexts.isSessionContextActive() ) {
			throw new IllegalStateException( "no session context active" );
		}
		return ( AuthenticationManagerBean ) Component.getInstance( AuthenticationManagerBean.class );
	}

	public static String getErrorfirma() {
		return ERROR_FIRMA;
	}
}

AuthenticatorAction.java

Sustituir la clase completa:

Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

import static org.jboss.seam.annotations.Install.FRAMEWORK;

import org.jboss.seam.annotations.Install;
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 es.um.atica.seam.security.authentication.AbstractAuthenticationManagerBean;
import es.um.atica.seam.security.authentication.AbstractAuthenticatorAction;

@Name( "authenticator" )
@Install( precedence = FRAMEWORK )
@BypassInterceptors
public class AuthenticatorAction extends AbstractAuthenticatorAction {

	private static final Log LOG = Logging.getLog( AuthenticatorAction.class );

	@Override
	protected AbstractAuthenticationManagerBean getAuthenticationManagerBean() {
		return AuthenticationManagerBean.instance();
	}

	/*
	 * (non-Javadoc)
	 * @see es.um.atica.util.FundeWebManagerBean#getLog()
	 */
	@Override
	protected Log getLog() {
		return LOG;
	}
}

messages_en.properties

Añadir al final del fichero las siguientes variables.

Bloque de código
themeEclipse
linenumberstrue
#------------- Páginas de error ------------
page.error.authmethod.title=Authentication method not supported
page.error.authmethod.desc=The authentication method used is not allowed for this application, The allowed methods:
page.error.authmethod.link.pre=To access the application, you must
page.error.authmethod.link=change the authentication method
page.error.authmethod.link.post=to one of those allowed.

page.error.noauth.title=You're not authorized
page.error.noauth.desc=Sorry, you are not authorized to perform this action.
page.error.noauth.link.pre=If you consider that you should have access, contact
page.error.noauth.link=the User Service Center
page.error.noauth.link.post=.

messages_es.properties

Añadir al final del fichero las siguientes variables.

Bloque de código
themeEclipse
linenumberstrue
#------------- Páginas de error ------------
page.error.authmethod.title=M\u00E9todo de autenticaci\u00F3n no soportado
page.error.authmethod.desc=El m\u00E9todo de autenticaci\u00F3n utilizado no es v\u00E1lido para esta aplicaci\u00F3n, solamente se permiten los m\u00E9todos:
page.error.authmethod.link.pre=Para acceder a la aplicaci\u00F3n debe
page.error.authmethod.link=cambiar de m\u00E9todo de autenticaci\u00F3n
page.error.authmethod.link.post=a uno de los permitidos.

page.error.noauth.title=Usted no est\u00E1 autorizado
page.error.noauth.desc=Lo siento, usted no est\u00E1 autorizado a realizar esta acci\u00F3n.
page.error.noauth.link.pre=Si considera que deber\u00EDa tener acceso, contacte con 
page.error.noauth.link=el Centro de Atenci\u00F3n a Usuarios
page.error.noauth.link.post=.

pages.xml

Añadir la siguiente regla de navegación:

Bloque de código
themeEclipse
linenumberstrue
<navigation from-action="#{identity.relogByCAS}">
	<redirect url="https://${cas.server.url}.um.es/cas/logout?service=https://${cas.application.url}/#{request.contextPath}" />
</navigation>

Añadir la siguiente excepción:

Bloque de código
themeEclipse
linenumberstrue
<exception class="es.um.atica.apium.security.authentication.AuthenticationMethodNotSupportedException">
	<redirect view-id="/error_auth_method.xhtml">
		<message severity="error">#{messages['es.um.atica.security.authentication.AuthenticationMethodNotSupportedException']}</message>
	</redirect>
</exception>

Modificar la excepción para la clase org.jboss.seam.security.AuthorizationException:

Bloque de código
themeEclipse
linenumberstrue
<exception class="org.jboss.seam.security.AuthorizationException">
	<redirect view-id="/error_no_auth.xhtml">
		<message severity="error">#{messages['org.jboss.seam.security.AuthorizationException']}</message>
	</redirect>
</exception>

ApiumIdentity.java

Modificar esta clase para añadir el método relogByCAS:

Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.core.Events;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;
import org.jboss.seam.web.Session;

import es.um.atica.seam.security.UmuIdentity;

@Name( "org.jboss.seam.security.identity" )
@Scope( ScopeType.SESSION )
@Install( precedence = Install.APPLICATION, classDependencies = "org.umu.atica.servicios.gesper.gente.entity.Persona" )
@BypassInterceptors
@Startup
public class ApiumIdentity extends UmuIdentity {

	private static final long serialVersionUID = 4315185968632267803L;
	private static final Log LOG = Logging.getLog( UmuIdentity.class );

	public static final String ROL_ADMINISTRADOR = "ADMIN";

	public boolean esUsuarioUmu() {
		return ( this.getPersona().getCorreo().endsWith( "@um.es" )
				|| this.getPersona().getCorreo().endsWith( "@ticarum.es" ) );
	}

	public static String getRolAdministrador() {
		return ROL_ADMINISTRADOR;
	}

	public void relogByCAS() {
		LOG.debug( "relogByCAS: #0", getCredentials().getUsername() );
		unAuthenticate();
		Session.instance().invalidate();
		if ( Events.exists() ) {
			Events.instance().raiseEvent( EVENT_LOGGED_OUT );
		}
	}
}

error_template.xhtml

Añadir template para páginas de error:

Bloque de código
languagexml
themeEclipse
linenumberstrue
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html version="-//W3C//DTD XHTML 1.1//EN" 
	lang="#{locale.language}" xmlns="http://www.w3.org/1999/xhtml"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:s="http://jboss.org/schema/seam/taglib"
	xmlns:p="http://primefaces.org/ui"
	xmlns:fdw="http://www.um.es/atica/fundeweb"
	xsi:schemaLocation="http://www.w3.org/1999/xhtml
                          http://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd">
<h:head>
	<f:facet name="first">
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<title><h:outputText value="#{messages['application.title']}" /></title>
		<!--  -->
		<link rel="shortcut icon" href="#{request.contextPath}/resources/img/icon.png" />
		<ui:insert name="head-first" />
	</f:facet>
	<f:facet name="last">
		<fdw:outputStylesheet library="fundeweb" name="primeflex/2_0/primeflex.min.css" />
		<!-- Personalizacion UMU -->
		<fdw:outputStylesheet library="themes" name="um/1_1/css/font.css" />
		<fdw:outputStylesheet library="themes" name="um/1_1/css/layoutUMU.css" />
		<fdw:outputStylesheet library="themes" name="um/1_1/css/estiloUMU.css" />

		<!-- Personalizacion de la aplicacion -->
		<fdw:outputStylesheet library="css" name="custom.css" />
	</f:facet>
</h:head>
<h:body>
	<f:view>
		<div id="main-wrapper" class="error-page">
			<header class="topbar">
				<nav class="navbar">
					<span class="app-name d-sm-none" style="margin-left: 73px;"> #{messages['application.name']} </span>
					<span class="app-name d-md-none"> #{messages['application.name']} </span>
				</nav>
			</header>
			<div class="page-wrapper">
				<div class="main-content" style="margin: 0;">
					<main class="page-content ui-g">
						<div class="ui-g-0 ui-lg-2"></div>
						<div class="ui-g-12 ui-lg-8">
							<ui:insert name="body" />
						</div>
					</main>
					<footer class="footerRow clearfix">
						<span>#{messages['application.foot.universidad']} — #{messages['application.foot.atica']}</span>

						<s:fragment rendered="#{init.debug}">
							<ui:include src="/layout/pie_debug.xhtml" />
						</s:fragment>
					</footer>
				</div>
			</div>
		</div>
	</f:view>
</h:body>
</html>

error_auth_method.xhtml

Añadir página de error en el método de autorización.

Bloque de código
languagexml
themeEclipse
linenumberstrue
<ui:composition template="error_template.xhtml"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:s="http://jboss.org/schema/seam/taglib"
	xmlns:p="http://primefaces.org/ui"
	xmlns:c="http://java.sun.com/jsp/jstl/core">

	<ui:define name="body">
		<h1 class="titulo-pagina">#{messages['page.error.authmethod.title']}</h1>
		<p class="text-size-big-4 font-weight-medium p-mt-5">
			#{messages['page.error.authmethod.desc']}
		</p>
		<ul>
			<c:forEach var="_authType" items="#{authenticationManagerBean.authenticationTypes}">
				<c:if test="#{not empty _authType.descKey}">
					<li>#{messages[_authType.descKey]}</li>
				</c:if>
			</c:forEach>
		</ul>

		<h:form>
			<p class="text-size-big-4 font-weight-medium p-mt-5" style="margin">
				#{messages['page.error.authmethod.link.pre']}
				<s:link action="#{identity.relogByCAS}" propagation="none"
						includePageParams="false" value="#{messages['page.error.authmethod.link']}" />
				#{messages['page.error.authmethod.link.post']}
			</p>
		</h:form>
	</ui:define>
</ui:composition>

error_no_auth.xhtml

Añadir página de error no autorizado.

{
			case SSO: // case SSO
			case SSO_CLAVE:
			//case SSO_CMN:
			case SSO_CERT:
				return new es.um.atica.apium.security.authentication.AuthenticationFactorySSO();
			case CORREO: // case CORREO
				return new AuthenticationFactoryCorreo();
			default:
				return new es.um.atica.apium.security.authentication.AuthenticationFactoryRadius();
		}
	}

	protected String getAuthenticationTypeLabel( AuthenticationType authenticationType ) {
		ResourceBundle srb = SeamResourceBundle.getBundle();

		try {
			return srb.getString( authenticationType.getDescKey() );
		} catch ( MissingResourceException mre ) {
			LOG.error( "Error al obtener las etiquetas para los tipos de autenticacion.", mre );
		}
		return "";
	}

	/**
	 * Obtiene la credencial actual.
	 */
	public CredentialsUmu getCredentialsUmu() {
		return this.credentialsAdapter.getCredentialsUmu();
	}

	public AuthenticationType getAuthenticationType() {
		return authenticationType;
	}

	public void setAuthenticationType( AuthenticationType authenticationType ) {
		LOG.debug( "Entra en setAuthenticationType: #0 - #1", authenticationType.hashCode(),
				authenticationType.name() );
		this.authenticationType = authenticationType;
	}

	public boolean isCorreoAuthentication() {
		return this.authenticationType == AuthenticationType.CORREO;
	}

	public boolean isSsoAuthentication() {
		return this.authenticationType == AuthenticationType.SSO;
	}

	public SelectItem[] getSelectItemsAutentication() {
		return selectItemsAutentication;
	}

	@Observer( UmuIdentity.EVENT_AUTHENTICATING_BY_CAS )
	public void activarAuthenticacionSSO() {
		LOG.debug( "Entra en activarAuthenticacionSSO" );
		this.authenticationType = AuthenticationType.SSO;
		this.activateCredentialsUmu();
	}

	/*
	 * (non-Javadoc)
	 * @see es.um.atica.util.FundeWebManager#getLog()
	 */
	@Override
	protected Log getLog() {
		return LOG;
	}

	public static AuthenticationManagerBean instance() {
		if ( !Contexts.isSessionContextActive() ) {
			throw new IllegalStateException( "no session context active" );
		}
		return ( AuthenticationManagerBean ) Component.getInstance( AuthenticationManagerBean.class );
	}

	public static String getErrorfirma() {
		return ERROR_FIRMA;
	}
}

AuthenticatorAction.java

Sustituir la clase completa:

Bloque de código
languagejava
themeEclipse
linenumberstrue
package es.um.atica.apium.security.authentication;

import static org.jboss.seam.annotations.Install.FRAMEWORK;

import org.jboss.seam.annotations.Install;
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 es.um.atica.seam.security.authentication.AbstractAuthenticationManagerBean;
import es.um.atica.seam.security.authentication.AbstractAuthenticatorAction;

@Name( "authenticator" )
@Install( precedence = FRAMEWORK )
@BypassInterceptors
public class AuthenticatorAction extends AbstractAuthenticatorAction {

	private static final Log LOG = Logging.getLog( AuthenticatorAction.class );

	@Override
	protected AbstractAuthenticationManagerBean getAuthenticationManagerBean() {
		return AuthenticationManagerBean.instance();
	}

	/*
	 * (non-Javadoc)
	 * @see es.um.atica.util.FundeWebManagerBean#getLog()
	 */
	@Override
	protected Log getLog() {
		return LOG;
	}
}



pages.xml

Añadir la siguiente regla de navegación en <page view-id="*">:

Bloque de código
themeEclipse
linenumberstrue
<navigation from-action="#{identity.relogByCAS}">
	<redirect url="https://${cas.server.url}.um.es/cas/logout?service=https://${cas.application.url}/#{request.contextPath}" />
</navigation>

Añadir la siguiente excepción:

Bloque de código
themeEclipse
linenumberstrue
    <exception class="es.um.atica.seam.security.authentication.exceptions.AuthenticationMethodNotSupportedException">
	    <redirect view-id="/fundeweb/error_auth_method.xhtml">
	        <message severity="error">#{messages['es.um.atica.security.authentication.AuthenticationMethodNotSupportedException']}</message>
	    </redirect>
	</exception>

Modificar la excepción para la clase org.jboss.seam.security.AuthorizationException:

Bloque de código
themeEclipse
linenumberstrue
	<exception class="org.jboss.seam.security.AuthorizationException">
		<redirect view-id="/fundeweb/error_no_auth.xhtml">
			<message severity="error">#{messages['org.jboss.seam.security.AuthorizationException']}</message>
		</redirect>
	</exception>
Bloque de código
languagexml
themeEclipse
linenumberstrue
<ui:composition template="error_template.xhtml"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:s="http://jboss.org/schema/seam/taglib"
	xmlns:p="http://primefaces.org/ui">

	<ui:define name="body">
		<h1 class="titulo-pagina">#{messages['page.error.noauth.title']}</h1>
		<div class="text-size-big-4 font-weight-medium">
			<p class="p-mt-5">#{messages['page.error.noauth.desc']}</p>
			<p>
				#{messages['page.error.noauth.link.pre']}<p:link class="text-size-big-4" href="https://www.um.es/web/atica/contacto" value="#{messages['page.error.noauth.link']}" />#{messages['page.error.noauth.link.post']}
			</p>
		</div>
	</ui:define>
</ui:composition>