======Autorización======
--- //[[pedrody@um.es|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: Restringe el acceso completo a la aplicación. Por lo tanto los usuarios que no estén autorizados no podrán entrar en la aplicación aunque sí estén autenticados.
* Autorización parcial: Restringe el acceso a partes de la aplicación. Los usuarios podrán entrar a la aplicación, pero solo tendrán acceso a las opciones y módulos para los cuales estén autorizados.
===== 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 [[fdw:fdw-gt-auth|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.
#{identity.hasPermission('PUESTO_PADRE',null)}
De la misma forma se procederá para los botones y enlaces que se quieran ocultar.