Tabla de Contenidos

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 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

 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:

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.

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.

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.

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.

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.

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.