Tabla de Contenidos

Autorización

PEDRO DELGADO YARZA 2014/01/29 13:55

A la hora de aplicar autorización a nuestras aplicaciones web, debemos distinguir entre dos tipos posibles de autorización: restrictiva y parcial:

Autorización restrictiva

Este tipo de autenticación bloqueará el acceso a los usuarios que no estén autenticados en la aplicación.

A la hora realizar la autenticación tenemos dos escenarios posibles: autenticación sin CAS y con CAS.

En ambos casos cargaremos los datos a comprobar en la clase Identity que estemos utilizando, y se cargarán a través de la clase UmuIdentityLoader, como se explica en la guia de carga de datos usuarios

Esta carga de datos la incluiremos en el metodo loadDataAuthenticate de la clase UmuIdentityLoader o de la clase que herede de ésta. Por ejemplo si cargamos los datos del puesto en el que esta incluido el usuario, añadiremos:

/**
  * 
  * Carga los datos de acceso de usuario. Puesto
  * 
*/
public void loadDataAuthentication(){
	Query query = entityManager.createNamedQuery("listaPuestoPrincipal");
	query.setParameter("user", identity.getCredentials().getUser());
	String puesto = (String) query.getSingleResult();
	identity.setPuesto(puesto);
 
}	

Autenticación sin CAS

Para implementar este tipo de autorización deberemos hacer lo siguiente:

Añadir al método authenticate que estará en la clase AuthenticatorAction o en las subclases AuthenticationMethodCard,AuthenticationMethodCertificate etc.., la carga y comprobación de los datos del usuario conectado.

Modificaremos el método de autenticación de la clase AuthenticatorAction o en las subclases AuthenticationMethodCard,AuthenticationMethodCertificate etc.., para que no permita pasar en caso de que el usuario no tenga acceso con ese puesto:

public boolean authenticate() {
//// Codigo de inicializacion
 
	try {
	 	//Atenticacion Radius u otra similar (tarjeta, certificado, etc..)
 
	    ServicioRadiusUmu servicioRadiusUmu = 
		(ServicioRadiusUmu) BuscadorServiciosAtica.obtenerServicio(ServicioRadiusUmu.ID);
 
		// si pasa la autenticacion Radius
		if ( servicioRadiusUmu.autentica(usuario, getIdentity().getCredentials().getPassword(), 
		    				"PORTAL FUNDEWEB")){
 
		 	// Comprobacion de que el usuario es de puesto tipo 1
			UmuIdentityLoader umuIdentityLoader = (UmuIdentityLoader) Component.getInstance(UmuIdentityLoader.class); 
			umuIdentityLoader.loadDataAuthentication(); 
			UmuIdentity umuIdentity  = (UmuIdentity) getIdentity();
			if ("1".equals(umuIdentity .getPuesto())){
				// no es de puesto 1 añadimos el error
		    	getStatusMessages().addFromResourceBundle(Severity.INFO, "No tiene puesto para acceder a la aplicación");
 
		    	return false;
			}
			else{
				// es de puesto uno y esta autenticado
		    	return true;
			}
                       ....
                       ....
    }

Autenticación con CAS

Para implementar este tipo de autorización deberemos hacer lo siguiente:

Deberemos modificar el método isLoggedIn que es el encargado de dar o no acceso a la aplicación y haremos el emulateLoginSeam sólo en caso de que se cumpla la condición.

	/**
     * Simple check that returns true if the user is logged in, without attempting to authenticate if is Seam Login CAS
     * Login attempt to
     *
     * @return true if the user is logged in
     */
    @Override
    public boolean isLoggedIn() {
    // If there is a principal set, then the user is logged in Seam.
    if (getPrincipal() != null) {
        return true;
    }
    else {
        // If there is a user in CASFilter.CAS_FILTER_USER, then the user is logged in CAS.
        String user = getUserLoggedInCas();
        log.debug("Usuario encontrado: #0", user);
        // Usuario no loggeado en Seam pero SI loggeado en CAS
        if (user != null) {
        	UmuIdentityLoader umuIdentityLoader = (UmuIdentityLoader) Component.getInstance(UmuIdentityLoader.class); 
			umuIdentityLoader.loadDataAuthentication();
 
			//comprueba que se hayan cargado correctamente los permisos de usuario 
        	if (hasApplicationSpecificPermission(user))
        	{
                // logueamos al usuario en Seam
                emulateLoginSeam(user);
                return true;
        	}
        	else {
            	return false;
        	}
        }
    }
    return false;
} 
 

Autorización parcial

Para realizar este tipo de autorización deberemos tener una estructura de base de datos que nos permita gestionar los roles y permisos dentro de la misma, lo que se plasma en una serie de tablas dentro de nuestro esquema. Dicha estructura debe contener el conceto Rol- Usuario - Permisos

Si esas tablas no pertenecen a nuestra aplicación o el esquema de permisos no tiene que ver con los conceptos Rol- Usuario - Permisos, sino a otros (cargo que ocupa, relación concreta con la universidad en afiliaciones etc..), procederemos del siguiente modo.

Cargaremos los datos de permisos, en el método loadDataLoginSuccessful de la clase UmuIdentityLoader Más tarde reimplementaremos el método hasPermission de UmuIdentity, para que tenga en cuenta los nuevos permisos de la forma:

@Override
public boolean hasPermission(Object target, String action)
{
  String targetString = (String) target;
  if ("PUESTO_PADRE".equals(targetString)){
  	if ("1".equals(getPuesto())){
	  return true;
	}
	else{
	  // NO tiene permisos. Redirigimos a otra pagina
	  return false;
	}
	}
    return super.hasPermission(target, action);
}

En el fichero page.xml de la página habrá que añadir una opción para restringir el acceso, ya que aunque no exista la opción de menú, algún usuario podría copiar la URL para acceder directamente a la página.

<restrict>#{identity.hasPermission('PUESTO_PADRE',null)}</restrict>

De la misma forma se procederá para los botones y enlaces que se quieran ocultar.