====== Infraestructura de autorización en aplicaciones Fundeweb 2.x ======
En Fundeweb 2 se ha realizado una implementación de la estructura de autorización para disponer de ella desde el inicio de nuestros proyectos, de manera que no tengamos que hacer un gran esfuerzo a la hora de implementar por completo toda la infraestructura, sino que partamos de una base sólida que podamos ampliar y/o modificar.
Esta estructura de autorización se basa en la propuesta en [[fdw2.0:fundeweb2.0:gt:gestion_de_roles_y_usuarios_con_tablas_de_base_de_datos|Gestión de Roles y Usuarios con tablas de Base de Datos]] creando una capa por encima con la funcionalidad necesaria para realizar la gestión básica de usuarios y permisos. Dejando como responsabilidad de los diferentes programadores la interpretación concreta de cada uno de esos permisos.
===== Diagrama de base de datos =====
{{ :fdw2.0:fundeweb2.0:gt:diagramabb.png | Tablas de base de datos usadas en la autorización}}
Como nota, del esquema de base de datos se puede deducir que la estructura de roles puede ser jerárquica, permitiendo tener roles y subroles y acumulando los permisos asociados a ellos.
Este es el script que genera este diagrama de tablas, parausarlo hay que **sustituir [MIESQUEMA] por el nombre de nuestro esquema BBDD**.
CREATE TABLE [MIESQUEMA].USUARIOS
(
LOGIN VARCHAR2(40 BYTE) NOT NULL
)
TABLESPACE [MIESQUEMA]
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 16K
NEXT 128K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX [MIESQUEMA].USUARIOS_PK ON [MIESQUEMA].USUARIOS
(LOGIN)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 32K
NEXT 32K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE [MIESQUEMA].USUARIOS ADD (
CONSTRAINT PK_USUARIOS
PRIMARY KEY
(LOGIN)
USING INDEX [MIESQUEMA].USUARIOS_PK
ENABLE VALIDATE);
GRANT DELETE, INSERT, SELECT, UPDATE ON [MIESQUEMA].USUARIOS TO JV_[MIESQUEMA];
CREATE TABLE [MIESQUEMA].ROLES
(
ID_ROL VARCHAR2(20 BYTE) NOT NULL,
DESCRIPCION VARCHAR2(50 BYTE),
ROL_PADRE VARCHAR2(20 BYTE)
)
TABLESPACE [MIESQUEMA]
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 16K
NEXT 128K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX [MIESQUEMA].ROLES_PK ON [MIESQUEMA].ROLES
(ID_ROL)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 32K
NEXT 32K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE [MIESQUEMA].ROLES ADD (
CONSTRAINT PK_ROLES
PRIMARY KEY
(ID_ROL)
USING INDEX [MIESQUEMA].ROLES_PK
ENABLE VALIDATE);
ALTER TABLE [MIESQUEMA].ROLES ADD (
CONSTRAINT ROLES_R01
FOREIGN KEY (ROL_PADRE)
REFERENCES [MIESQUEMA].ROLES (ID_ROL)
ENABLE VALIDATE);
GRANT DELETE, INSERT, SELECT, UPDATE ON [MIESQUEMA].ROLES TO JV_[MIESQUEMA];
CREATE TABLE [MIESQUEMA].OBJETIVOS
(
ID_OBJETIVO VARCHAR2(20 BYTE) NOT NULL,
DESC_OBJETIVO VARCHAR2(50 BYTE)
)
TABLESPACE [MIESQUEMA]
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX [MIESQUEMA].OBJETIVOS_PK ON [MIESQUEMA].OBJETIVOS
(ID_OBJETIVO)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE [MIESQUEMA].OBJETIVOS ADD (
CONSTRAINT OBJETIVOS_PK
PRIMARY KEY
(ID_OBJETIVO)
USING INDEX [MIESQUEMA].OBJETIVOS_PK
ENABLE VALIDATE);
GRANT DELETE, INSERT, SELECT, UPDATE ON [MIESQUEMA].OBJETIVOS TO JV_[MIESQUEMA];
CREATE TABLE [MIESQUEMA].USUARIOS_ROLES
(
COD_ROL VARCHAR2(3 BYTE) NOT NULL,
COD_USUARIO VARCHAR2(10 BYTE)
)
TABLESPACE [MIESQUEMA]
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 16K
NEXT 128K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX [MIESQUEMA].USUARIOS_ROLES_ROL ON [MIESQUEMA].USUARIOS_ROLES
(COD_ROL, COD_USUARIO)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 32K
NEXT 32K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
CREATE INDEX [MIESQUEMA].FK_USU ON [MIESQUEMA].USUARIOS_ROLES
(COD_USUARIO)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 0
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 16K
NEXT 16K
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE [MIESQUEMA].USUARIOS_ROLES ADD (
CONSTRAINT PK_USUARIOS_ROLES
PRIMARY KEY
(COD_ROL, COD_USUARIO)
USING INDEX [MIESQUEMA].USUARIOS_ROLES_ROL
ENABLE VALIDATE);
ALTER TABLE [MIESQUEMA].USUARIOS_ROLES ADD (
CONSTRAINT FK_ROL
FOREIGN KEY (COD_ROL)
REFERENCES [MIESQUEMA].ROLES (ID_ROL)
ON DELETE CASCADE
ENABLE VALIDATE,
CONSTRAINT FK_USU
FOREIGN KEY (COD_USUARIO)
REFERENCES [MIESQUEMA].USUARIOS (LOGIN)
ON DELETE CASCADE
ENABLE NOVALIDATE);
GRANT DELETE, INSERT, SELECT, UPDATE ON [MIESQUEMA].USUARIOS_ROLES TO JV_[MIESQUEMA];
CREATE TABLE [MIESQUEMA].ROLES_USUARIO
(
ID_ROL VARCHAR2(20 BYTE) NOT NULL,
LOGIN VARCHAR2(30 BYTE) NOT NULL,
ID_ROL_USU NUMBER(19) NOT NULL
)
TABLESPACE [MIESQUEMA]
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX [MIESQUEMA].ROLES_USUARIO_PK ON [MIESQUEMA].ROLES_USUARIO
(ID_ROL_USU)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE [MIESQUEMA].ROLES_USUARIO ADD (
CONSTRAINT ROLES_USUARIO_PK
PRIMARY KEY
(ID_ROL_USU)
USING INDEX [MIESQUEMA].ROLES_USUARIO_PK
ENABLE VALIDATE);
ALTER TABLE [MIESQUEMA].ROLES_USUARIO ADD (
CONSTRAINT ROLES_USUARIO_R01
FOREIGN KEY (ID_ROL)
REFERENCES [MIESQUEMA].ROLES (ID_ROL)
ENABLE VALIDATE);
GRANT DELETE, INSERT, SELECT, UPDATE ON [MIESQUEMA].ROLES_USUARIO TO JV_[MIESQUEMA];
CREATE TABLE [MIESQUEMA].ROLES_OBJETIVOS
(
ID NUMBER NOT NULL,
ID_ROL VARCHAR2(20 BYTE) NOT NULL,
ID_OBJETIVO VARCHAR2(20 BYTE) NOT NULL,
ACCION VARCHAR2(20 BYTE) NOT NULL
)
TABLESPACE [MIESQUEMA]
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
CREATE UNIQUE INDEX [MIESQUEMA].ROLES_OBJETIVOS_PK ON [MIESQUEMA].ROLES_OBJETIVOS
(ID)
LOGGING
TABLESPACE IND[MIESQUEMA]
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;
ALTER TABLE [MIESQUEMA].ROLES_OBJETIVOS ADD (
CONSTRAINT ROLES_OBJETIVOS_PK
PRIMARY KEY
(ID)
USING INDEX [MIESQUEMA].ROLES_OBJETIVOS_PK
ENABLE VALIDATE);
ALTER TABLE [MIESQUEMA].ROLES_OBJETIVOS ADD (
CONSTRAINT ROLES_OBJETIVOS_R01
FOREIGN KEY (ID_ROL)
REFERENCES [MIESQUEMA].ROLES (ID_ROL)
ENABLE VALIDATE,
CONSTRAINT ROLES_OBJETIVOS_R02
FOREIGN KEY (ID_OBJETIVO)
REFERENCES [MIESQUEMA].OBJETIVOS (ID_OBJETIVO)
ENABLE VALIDATE);
GRANT DELETE, INSERT, SELECT, UPDATE ON [MIESQUEMA].ROLES_OBJETIVOS TO JV_[MIESQUEMA];
CREATE SEQUENCE [MIESQUEMA].ROL_OBJETIVO_SEQ
START WITH 0
MAXVALUE 9999999999999999999999999999
MINVALUE 0
NOCYCLE
NOCACHE
NOORDER;
GRANT SELECT ON [MIESQUEMA].ROL_OBJETIVO_SEQ TO JV_[MIESQUEMA];
CREATE SEQUENCE [MIESQUEMA].ROL_USUARIO_SEQ
START WITH 0
MAXVALUE 9999999999999999999999999999
MINVALUE 0
NOCYCLE
NOCACHE
NOORDER;
GRANT SELECT ON [MIESQUEMA].ROL_USUARIO_SEQ TO JV_[MIESQUEMA];
===== Creación de la infraestructura de autorización =====
Una vez con el esquema de base de datos creado, estamos en disposición de cargar las clases y vistas que harán posible tener nuestra infraestructura de autorización. Para ello tenemos dos opciones:
* **No tenemos ningún proyecto creado:** En este punto basta con crear el proyecto a partir del arquetipo que incluye la gestión de autorización.
* **Tenemos ya un proyecto creado:** La manera más rápida es crear un proyecto vacío con el arquetipo que incluye la autorización y copiar las clases a nuestro proyecto.
Una vez tengamos el código fuente, la aplicación podrá dar de alta usuarios y asignarle roles. Estos roles tendrán asociados a su vez objetivos y acciones que también podrán ser dados de alta desde la aplicación.
Por parte del programador queda implementar la parte que da sentido a los permisos partiendo del siguiente código base:
@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 AplicacionIdentity extends UmuIdentity {
private static final long serialVersionUID = 4315185968632267803L;
@Override
public boolean hasPermission(Object objetivo, String accion) {
if (hasRole("ADMIN")) {
return true;
} else {
return super.hasPermission(objetivo, accion);
}
}
}
Una vez preparado todo desplegamos el código y accedemos a la sección de gestión de usuarios. En ella tendremos cuatro pestañas para gestionar todo lo concerniente a la autorización, roles y permisos de los mismos.
A continuación comentamos las diferentes pestañas:
===== Usuarios-Roles =====
Esta pestaña será la que nos permita la creación/edición de usuarios y asignación/eliminación de sus respectivos roles.
{{ :fdw2.0:fundeweb2.0:gt:1.usuario-roles.png |}}
En esta pestaña podremos crear un nuevo usuario, para ello introduciremos su correo,nombre o apellidos y le daremos al botón buscar. Éste cargará un listado de todos los usuarios UMU que cumplen con el filtro establecido. Una vez obtenido el listado, seleccionaremos el usuario al que queramos dar de alta.
Una vez hecho esto buscamos al usuario en la tabla de usuarios y hacemos clic sobre él para gestionar sus roles que aparecerán en forma de árbol a la derecha de la tabla. Haciendo clic en los checks se irán asignando/eliminando los diferentes roles al usuario.
Si queremos eliminar al usuario basta con pinchar en el icono de la papelera.
===== Roles-Usuarios =====
Esta pestaña será la que nos permita la creación/edición de los roles de nuestra aplicación, así como ver los usuarios que tiene un determinado rol pudiendo gestionar su pertenencia o no.
{{ :fdw2.0:fundeweb2.0:gt:2.roles-usuarios.png |}}
En esta pestaña podremos ver una estructura de árbol con todos los roles que dispone nuestra aplicación así como toda la información relativa a cada rol.
Al hacer clic sobre un rol del árbol se nos cargará a la derecha un listado de todos los usuarios que tienen dicho rol, permitiéndonos quitárselo. Adicionalmente hay un check //Mostrar todos// que permite mostrar todos los usuarios de la aplicación y asignarles el rol seleccionado si no lo tuvieran.
Bajo esa tabla podemos observar otra que nos muestra los objetivos que tiene el rol seleccionado asignados y las acciones que se permiten sobre dichos objetivos.
===== Roles-Objetivos =====
En esta pestaña podremos definir para cada rol que objetivos tiene y qué acciones podrá realizar sobre dichos objetivos.
{{ :fdw2.0:fundeweb2.0:gt:3.roles-objetivos.png |}}
Situado a la izquierda tendremos el árbol de roles, igual que en la pestaña anterior, y a la derecha tendremos una tabla que nos permitirá, para el rol seleccionado asignar o eliminar objetivos y acciones.
Para ello pulsaremos el botón **Nuevo** de dicha tabla y en el desplegable que aparece escribiremos el nombre de la acción a realizar y seleccionaremos en el desplegable los objetivos a los que queremos asignarle esta acción.
{{ :fdw2.0:fundeweb2.0:gt:3.1.crearaccion.png |}}
===== Objetivos-Roles =====
En esta pestaña podremos definir los diferentes objetivos/acciones de nuestra aplicación, así como ver qué objetivos están cubiertos por qué roles.
{{ :fdw2.0:fundeweb2.0:gt:4objetivos-roles.png |}}
En la tabla de la izquierda podremos ver todos los objetivos junto con su descripción y en la de la derecha las acciones que posee el objetivo seleccionado y los roles que pueden ejecutar dicha acción.
Dándole al botón **Nuevo** podremos asignar nuevas acciones a los objetivos existentes de igual manera que en el apartado anterior.