openxava / documentación / Seguridad y gestión de usuarios

Tabla de contenidos

Seguridad y gestión de usuarios
Gestión de usuarios
Restringir el acceso a ciertas acciones
Restringir el acceso a ciertas propiedades, referencias o colecciones (nuevo en v5.5)
Módulo de sólo lectura con un solo clic (nuevo en v7.2)
Ocultar un módulo en el menú sin restringirlo (nuevo en v6.5)
Desactivar personalización de la lista (nuevo en v7.4)
Políticas para usuarios y contraseñas
LDAP
Código de autentificación LDAP personalizado (nuevo en v7.4)
Invitado puede crearse una cuenta de usuario él mismo
Fecha de creación de usuario y registro de inicios de sesión
Recuperación de contraseña (nuevo en v5.7)
Se le pide al usuario su correo electrónico
Correo electrónico como nombre de usuario (nuevo en in v6.0)
Restringir acceso por IP (nuevo en v6.4)
Código de autentificación personalizado (nuevo en
v7.0)
Página de identificación (login) personalizada (nuevo en v7.1)
Single Sign-On (SSO) (nuevo en v7.1)
Autentificación en dos pasos (2FA) (nuevo en v7.1)
Todas las funcionalidades en este artículo están disponible solo en XavaPro

Gestión de usuarios

XavaPro añade los módulos Roles, Módulos y Usuarios a tu aplicación, en una carpeta llamada Admin. Estos módulos te permiten configurar los niveles de acceso para los diferentes tipos de usuarios.
naviox-roles_es.png
Lo normal es crear un nuevo rol y asignarle algunos módulos. Entonces, en el módulo Usuarios, puedes escoger un usuario y asignarle el nuevo rol. Por defecto hay dos roles ya creados: admin con acceso a Usuarios, Roles, Módulos y Carpetas, y user con acceso a todos los módulos de tu aplicación. Los módulos nuevos no se añaden automáticamente al rol user (ni ningún otro rol), por lo que has de añadir los nuevos módulos explícitamente al rol user (o cualquier otro rol) usando el módulo Roles.
Si quitas el acceso al módulo por defecto de una entidad, modificar y crear desde las referencias a esa entidad no estará disponible. Por ejemplo, si los usuarios de cierto rol no pueden acceder al módulo Cliente, tampoco podrán crear y modificar clientes desde el módulo Factura (nuevo en v5.3).
Esta gestión de usuarios está disponible sólo en XavaPro, con el OpenXava normal tienes que añadir los usuarios en el fichero naviox-users.properties. de la carpeta properties de tu proyecto.

Restringir el acceso a ciertas acciones

Si quieres que los usuarios de un determinado rol no pueda ejecutar algunas acciones, ve al módulo Roles y escoge ese rol para editarlo en modo detalle. Ahora haz click en el módulo donde quieras restringir las acciones. Te aparecerá un diálogo como este:
xavapro-restrict-actions_es.png
Selecciona las acciones que quieras excluir y pulsar Grabar. A partir de ahora, todos los usuario de ese rol no podrán ejecutar esas acciones en ese módulo.
Restringir el acceso a Nuevo y Grabar también restringe la posibilidad de crear y modificar desde las referencias, si se hace en el módulo por defecto para esa entidad. Por ejemplo, si restringes el acceso a la acción Grabar en el módulo Cliente, el usuario no podrá modificar los datos de Cliente desde el módulo Factura (nuevo en v5.3).
Restringir el acceso a acciones sólo está disponible en XavaPro.

Restringir el acceso a ciertas propiedades, referencias o colecciones (nuevo en v5.5)

Si quieres que los usuarios de un determinado rol no pueda acceder a ciertas propiedades, referencias o colecciones, ve al módulo Roles y escoge ese rol para editarlo en modo detalle. Ahora haz click en el módulo donde quieras restringir el acceso a los miembros. Te aparecerá un diálogo como este:
restrict-data-read-only-data-xavapro_es.png
Selecciona los miembros en Datos excluidos que quieras excluir y pulsar Grabar. A partir de ahora, todos los usuario de ese rol no podrán acceder a esos miembros. Fíjate que también tenemos Datos de solo lectura para marcar miembros que los usuarios del rol podrán leer pero no modificar.
Restringir el acceso a miembros sólo está disponible en XavaPro.

Módulo de sólo lectura con un solo clic (nuevo en v7.2)

Desde la versión 5.5, tienes la capacidad de designar datos específicos como de solo lectura para un rol particular y controlar las acciones disponibles para ese rol. Con esta característica, puedes hacer que un módulo sea de solo lectura para un rol en particular de manera sencilla. Sin embargo, este enfoque tenía sus inconvenientes, especialmente cuando se introducían nuevos campos a la entidad, ya que requería ajustes constantes en la configuración.
Para abordar estos desafíos, a partir de la versión 7.2, el cuadro de diálogo de configuración de derechos del módulo para un rol ahora incluye una práctica casilla de verificación denominada Sólo lectura. Esta casilla te permite marcar un módulo como de solo lectura para el rol seleccionado con un solo clic, simplificando significativamente el proceso:
readonly-module-for-role_es.png
Un módulo de sólo lectura tiene todos los miembros no editables y sólo tiene acciones de navegación e impresión.
Los módulos de sólo lectura sólo están disponible en XavaPro.

Ocultar un módulo en el menú sin restringirlo (nuevo en v6.5)

Si quieres que un módulo no se muestre en el menú para los usuarios de ciertos roles pero que al mismo tiempo ese módulo sea accesible por esos usuarios, tecleando la URL en el navegador, por ejemplo. Ve al módulo Roles y escoge el rol que quieras editar en modo detalle, una vez allí pulsa en el módulo que quieras ocultar en el menú y un diálogo como el siguiente aparecerá:
hide-module-in-menu-for-role_es.png
Marca la opción No en el menú y pulsa en Grabar. A partir de ahora, todos los usuario de ese rol no verán el módulo, Customer en nuestro ejemplo, en el menú de la izquierda, sin embargo, seguirá estando disponible, por lo que si el usuario va a http://tusitio.com/TuAplicacion/m/Customer con su navegador el módulo funcionará.
Ocultar módulos en el menú sólo está disponible en XavaPro.

Desactivar personalización de la lista (nuevo en v7.4)

OpenXava permite a los usuarios personalizar la lista a su gusto añadiendo, quitando o moviendo columnas. Por supuesto, XavaPro nunca ha permitido que el usuario pueda añadir propiedades a las que ese usuario no tenga acceso por la configuración de permisos de XavaPro. Además, desde siempre OpenXava ha permitido desactivar esta característica a nivel global (para todos los módulos y usuarios) poniendo customizeList=false en xava.properties. Pero no es suficiente cuando se quiere que ciertos usuarios no tengan la posibilidad de personalizar la lista en absoluto, pero otros sí. Para eso, desde la versión 7.4 es posible desactivar la posibilidad de personalizar la lista para los usuarios de un rol específico. Para desactivar la personalización de la lista ve al módulo de roles, escoge un rol y desde ahí escoge un módulo. Esto mostrará el cuadro de diálogo de configuración de derechos del módulo para un rol, que ahora incluye una casilla de verificación denominada No personalizar lista. Márcala para desactivar la personalización de la lista para ese módulo, para usuarios de ese rol:
no-list-customization_es.png
Desactivar la personalización de la lista por roles sólo está disponible en XavaPro.

Políticas para usuarios y contraseñas

Hay un montón de opciones para configurar las políticas de gestión de usuarios y contraseñas. En la carpeta Admin encontrarás un módulo Configuración:
xavapro-configuration_es.png
Puedes configurar estas políticas para que tu sistema sea compatible con PCI-DSS, algo muy útil en aplicaciones bancarias.
La opcion Permitir varias sesiones por usuario (nueva en v7.4) permite que el mismo nombre de usuario pueda ser usado por varios personas diferentes desde diferentes máquinas/navegadores al mismo tiempo. Esto permite desactivar una característica introducida en v7.3 que hacía que al identificarse con un nombre de usuario si ese usuario tenía una sesión iniciada desde otra máquina o navegador, esa sesión se cancelara, forzando que un mismo usuario sólo pudiera estar identificado una vez al mismo tiempo.
Estas políticas para usuarios y contraseñas sólo están disponible en XavaPro.

LDAP

XavaPro permite a los usuarios ser autentificados vía LDAP. Para configurar LDAP edita el archivo naviox.properties y añade las siguientes entradas:
# Configuración LDAP
ldapHost=192.168.0.0
ldapDomain=XX
ldapDN=DC=XX,DC=XX,DC=XX
ldapPort=389
Si usas OpenLDAP omite la entrada ldapDomain (a partir de v5.9.1), como en este ejemplo:
# Ejemplo de configuración OpenLDAP
ldapHost=192.168.2.xxx
ldapDomain=
ldapDN=ou=people,dc=dgrtdf,dc=gov,dc=ar
ldapPort=389
Fíjate como ldapDomain no tiene valor.
Por defecto todos los usuarios son autentificados usando las contraseñas almacenadas por XavaPro. Para activar LDAP has de seleccionar los usuarios y marcar la opción Autentificar con LDAP:
naviox_ldap_es.png
El soporte de LDAP sólo está disponible en XavaPro.

Código de autentificación LDAP personalizado (nuevo en v7.4)

Para definir tu propia lógica de autentificación de usuarios contra tu servidor LDAP has de crear una clase que implemente la interfaz ILDAPAuthenticatorProvider. A veces la lógica por defecto con la que cuenta XavaPro para identificarse contra el servidor LDAP no es suficiente, puede que quieras identificarte contra varios servidores LDAP, contra un servidor LDAP especial que requiera un código especial, etc. En estos casos puedes definir la manera en que XavaPro autentifica a los usuarios contra LDAP en tu aplicación, para eso extiende ProLDAPAuthenticatorProvider, de esta manera:
package com.miempresa.miaplicacion.impl;

import java.util.*;

import javax.naming.*;
import javax.naming.directory.*;

import org.apache.commons.logging.*;
import org.openxava.util.*;

import com.openxava.naviox.impl.*;

public class MiPropioLDAPAuthenticatorProvider extends ProLDAPAuthenticatorProvider {
    
    private static Log log = LogFactory.getLog(MiPropioLDAPAuthenticatorProvider.class);    
    
    public boolean isValidLogin(String user, String password) {
        // Este código es un ejemplo de lógica para acceder a LDAP,
        // tendrás que escribir la tuya propia
        Hashtable<String, String> props = new Hashtable<String, String>();        
        String ldapDomain = getProperties().getProperty("ldapDomain", "").trim();
        String ldapHost = getProperties().getProperty("ldapHost", "").trim();
        String ldapPort = getProperties().getProperty("ldapPort", "").trim();
        String ldapDN =  getProperties().getProperty("ldapDN", "").trim();
        String ldapProtocol = "636".equals(ldapPort)?"ldaps":"ldap";         
        String ldapURL;        
        String securityPrincipal;
        if (Is.emptyString(ldapDomain)) {  
            ldapURL = String.format("%s://%s:%s", ldapProtocol, ldapHost, ldapPort); 
            securityPrincipal = String.format("%s%s%s", "uid=" + user,         
                                                           ldapDN.equals("")?"":",", 
                                                           ldapDN);    
        }
        else {     
            ldapURL = String.format("%s://%s:%s/%s", ldapProtocol, ldapHost, ldapPort, ldapDN); 
            securityPrincipal = String.format("%s%s%s", ldapDomain, 
                                                        ldapDomain.equals("")?"":"\\", 
                                                        user);
        }
        
        props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        props.put(Context.PROVIDER_URL, ldapURL);
        props.put(Context.SECURITY_AUTHENTICATION, "simple");
        props.put(Context.SECURITY_PRINCIPAL, securityPrincipal);
        props.put(Context.SECURITY_CREDENTIALS, password);
        props.put("com.sun.jndi.ldap.connect.timeout", "60000"); 
        try {
            DirContext ctx = new InitialDirContext(props);
            ctx.close();
            return true;
        } catch (NamingException ex) {
            log.error(XavaResources.getString("ldap_authentication_error"), ex);  
        } finally {
            log.info("javax.naming.Context.PROVIDER_URL: " + ldapURL);
            log.info("javax.naming.Context.SECURITY_PRINCIPAL: " + securityPrincipal);
        }
        return false;
    }
    
}
En este ejemplo la lógica usada es la forma típica de conectarse a un servidor LDAP y es muy parecida a la que usa XavaPro por defecto, tu tendrás escribir aquí tu propia lógica. Esta lógica de autentificación solo se aplica a los usuarios marcados con Autentificar con LDAP.
Para que tu aplicación use la clase de arriba para autentificación contra LDAP has de añadir la siguiente entrada en el archivo naviox.properties de tu proyecto:
ldapAuthenticatorProviderClass=com.miempresa.miaplicacion.impl.MiPropioLDAPAuthenticatorProvider
El soporte para definir una lógica propia para autentificarse con LDAP sólo está disponible en XavaPro.

Invitado puede crearse una cuenta de usuario él mismo

En la caja de identificación hay un vínculo etiquetado como CREAR CUENTA:
login-with-signup_es.png
El usuario puede pulsar en él para ir a un formulario de registro:
signup-form_es.png
Después de rellenar el formulario y pulsar el botón la cuenta de usuario se crea y además se inicia la sesión. Hay un rol self sign up para determinar los permisos de los usuarios autocreados.
Esta característica se puede desactivar en el módulo de configuración.
A partir de la v6.0 se puede mostrar una política de privacidad en la página de registro, el texto de la política de privacidad se obtiene de la entrada privacy_policy en los archivos de mensajes i18n. Es obligatorio que el usuario marque la casilla aceptando la política para poder hacer el registro. La fecha de la aceptación de la política se almacena junto con los datos del usuario. Puedes ocultar la política de privacidad usando el módulo de configuración.

Fecha de creación de usuario y registro de inicios de sesión

Ve al módulo de usuarios para ver esta información:
user-creation-date-sessions_es.png

Recuperación de contraseña (nuevo en v5.7)

El usuario puede recuperar su contraseña por sí mismo. Cuando falla al introducir la contraseña correcta se muestra un mensaje "¿Has olvidado tu contraseña?" con un vínculo:
recover-password-login_es.png
Cuando el usuario pulsa en el vínculo va a una página para introducir su correo electrónico:
enter-email-recover-password_es.png
Después de pulsar en el botón "Recuperar contraseña" un correo electrónico con instrucciones para recuperar la contraseña es enviado. Por supuesto, un usuario con ese correo electrónico ha de estar registrado en el sistema.
Para usar la funcionalidad de recuperación de contraseña has de configurar las propiedades de correo electrónico en xava.properties, algo como esto:
#SMTP related information
smtpHost=smtp.gmail.com
smtpPort=587
smtpUserId=micorreo@gmail.com
smtpUserPassword=micontrasena
smtpHostTrusted=true
smtpStartTLSEnable=true

Se le pide al usuario su correo electrónico

Para que este mecanismo de recuperación de contraseña funcione es necesario que cada usuario tenga su correo electrónico registrado en el sistema. Por tanto ahora si el usuario no tiene correo electrónico XavaPro se lo pregunta después de entrar:
enter-email-personal-data_es.png
Introducir el correo no es obligatorio, el usuario puede irse a cualquier otro módulo dejando el correo electrónico en blanco.
Este nuevo módulo "Mis datos personales" esta siempre disponible para que todos los usuarios puedan modificar sus propios datos personales.
Para desactivar esta característica y así que no se le pregunte al usuario por su correo electrónico cada vez que se identifique, has de quitar el módulo "Mis datos personales" del rol del usuario.

Correo electrónico como nombre de usuario (nuevo en v6.0)

En el módulo de configuración hay una opción llamada Usar correo electrónico como nombre de usuario. Si la marcas será obligatorio que el usuario se registre usando un correo electrónico como nombre de usuario. Además, los usuarios ya creados pueden identificarse usando su cuenta de correo en lugar de su nombre.
La validación del correo electrónico al registrarse se puede personalizar con emailValidatorForSignUpClass en naviox.properties, por ejemplo:
emailValidatorForSignUpClass=com.miempresa.miaplicacion.MiValidadorCorreo
En este caso la lógica de MiValidadorCorreo (ha de implementar IPropertyValidator) se aplica al correo electrónico al registrarse. La validación por defecto para el correo electrónico verifica que la sintaxis es correcta, pero a veces queremos una validación diferente, como que sea un correo de empresa, por ejemplo. Puede hacer eso con tu propio validador de correo electrónico.

Restringir acceso por IP (nuevo en v6.4)

Es posible definir una "IP permitida" para un usuario de tal manera que ese usuario sólo pueda acceder desde esa IP. Para ello, ve al módulo Usuarios en la carpeta Admin, escoge un usuario y dale valor al campo IP permitida:
allowed-ip_es.png
Finalmente, pulsa en Grabar. Si el valor de IP permitida es blanco el usuario puede acceder desde cualquier IP.

Código de autentificación personalizado (nuevo en v7.0)

Para definir tu propia lógica de autentificación de usuarios has de crear una clase que implemente la interfaz ISignInHelperProvider. El caso típico sería refinar la manera estándar en que XavaPro autentifica a los usuarios, para eso extiende ProSignInHelperProvider, de esta manera:
package com.miempresa.miaplicacion.impl;

import javax.servlet.*;
import org.openxava.util.*;
import com.openxava.naviox.impl.*;

public class MiPropioSignInHelperProvider extends ProSignInHelperProvider {
	
    @Override
    public boolean isAuthorized(
		ServletRequest request, String userName, 
		String password, Messages errors, String unauthorizedMessage) 
	{
        // Esta es tu lógica personalizada de autentificación
        if (userName.equals("admin") && password.equals("masterkey")) return true; 
		
		
        // Aquí delegamos en la lógica de autentificación por defecto de XavaPro
        return super.isAuthorized(request, userName, password, errors, unauthorizedMessage);
    }

}
En este caso la lógica es simple, si el usuario teclea "masterkey" como clave para el usuario "admin" el usuario accede a la aplicación como "admin", en caso contrario se aplica la lógica de autentificación por defecto de XavaPro. Sin embargo, aquí puedes escribir cualquier lógica que quieras, incluyendo llama a servicios web, leer tu propia base de datos de usuarios, consultar tu directorio LDAP en la manera que tu quieras, etc.
Para que tu aplicación use la clase de arriba para autentificación has de añadir la siguiente entrada en el archivo naviox.properties de tu proyecto:
signInHelperProviderClass=com.miempresa.miaplicacion.impl.MiPropioSignInHelperProvider

Página de identificación (login) personalizada (nuevo en v7.1)

Para definir tu propia página de identificación de usuario (página de login) crea un JSP dentro de la carpeta src/main/webapp/naviox de tu proyecto, puede que necesites crear la carpeta naviox. Por ejemplo, puedes crear un miSignIn.jsp (o cualquier otro nombre excepto signIn.jsp) con este contenido:
<div>Hola, soy un página de identificación personalizada</div>
<div>
<jsp:include page="signIn.jsp"/>
</div>
En este caso incluimos la página de identificación original (signIn.jsp) añadiendo algún contenido adicional, pero puedes crear la página desde cero, o incluir tu propio módulo OpenXava (mira el código original de signIn.jsp) que use tu propia entidad y controladores.
Para que la aplicación use la susodicha página de identificación has de añadir la siguiente entrada en el archivo naviox.properties de tu proyecto:
signInJSP=miSignIn.jsp

Single Sign-On (SSO) (nuevo en v7.1)

A partir de XavaPro 7.1 puedes usar Azure AD para proporcionar SSO a tus aplicaciones OpenXava. Mira la guía SSO con Azure AD.

Autentificación en dos pasos (2FA) (nuevo in v7.1)

A partir de XavaPro 7.1 puedes usar Azure AD para proporcionar autentificación en dos pasos a tus aplicaciones OpenXava. Mira la guía SSO con Azure AD.