Seguridad
Visión general
Crono ofrece varias formas de restringir el acceso a los datos:
- Un sistema de permisos extensible y organizado jerárquicamente, donde los permisos se asignan a roles y estos a los usuarios.
IAclRestringidomarca una entidad con derechos de acceso restringidos: solo los usuarios de ciertos roles pueden verla o accederla.- Herramientas de protección adicionales: token anti-falsificación, captcha, honeypot y protección contra sobrecarga.
Árbol de permisos
Los permisos se organizan como un árbol. Un permiso se concede cuando él mismo o alguno de sus permisos padre está concedido (y lo mismo para la denegación). Así, un permiso padre puede activar grupos completos de permisos, y los hijos heredan de cualquier ancestro. Por tanto, un permiso puede tener cuatro estados: Permitido, Denegado, Permitido heredado y Denegado heredado.
Los permisos se definen como constantes en la clase estática Permisos, siguiendo la convención de nombres en minúsculas separados por puntos, donde _ representa el permiso raíz de cada grupo:
public static partial class Permisos
{
public static partial class Sistema
{
public const string _ = "sistema";
public const string AccesoBackend = "sistema.accesobackend";
public static class Mantenimiento
{
public const string _ = "sistema.mantenimiento";
public const string Leer = "sistema.mantenimiento.leer";
}
}
}
Autorización
Usa IPermisoServicio para comprobar si un permiso está concedido a un usuario. Espera el nombre de sistema del permiso (usa las constantes de Permisos):
if (await _permisoServicio.AutorizarAsync(Permisos.Sistema.Mantenimiento.Leer))
{
// Acceso concedido
}
Existe también la versión síncrona Autorizar(...). Ambas aceptan opcionalmente el Usuario y un permitePorPermisoHijo.
En los métodos de acción se usa el atributo Permiso en lugar del servicio:
[Permiso(Permisos.Sistema.Mantenimiento.Leer)]
public async Task<IActionResult> Index()
{
// ...
}
Cuando el permiso no está concedido se lanza una excepción de acceso denegado; en peticiones AJAX se muestra una notificación y se devuelve la respuesta adecuada (HTML o JSON).
Agregar permisos personalizados
El sistema se extiende con IPermisoProveedor. Un proveedor declara los permisos a agregar y sus valores predeterminados:
public class MiModuloPermisoProveedor : IPermisoProveedor
{
public IEnumerable<Permiso> ObtenerPermisos() { /* ... */ }
public IEnumerable<PermisoPredeterminado> ObtenerPermisosPredeterminados() { /* ... */ }
}
Se recomienda usar el singular para los nombres de permiso y definir un permiso raíz _ sin puntos por convención. La localización se hace por convención mediante recursos de cadena. Los permisos de un módulo se agregan automáticamente al instalarlo y se eliminan al desinstalarlo (los detecta e instala InstalarPermisosAsync a partir de los proveedores registrados).
Lista de control de acceso (ACL)
Una entidad admite acceso restringido cuando implementa IAclRestringido: permite limitarla a ciertos roles. Solo los usuarios asignados a uno de esos roles pueden verla.
- Usa
IAclServiciopara comprobar si el usuario tiene derecho a acceder a una entidad. - Para cargar de la base de datos únicamente las entidades a las que el usuario tiene acceso, usa la extensión de consulta
AplicarFiltroAcl(IAclRestringidoConsultaExtensiones). - Para modificar los derechos de acceso de una entidad (normalmente al editarla), usa los métodos de
IAclServicio.
La aplicación del ACL en el guardado la refuerza el AclRestringidoInterceptor (ver Interceptores).
Herramientas de protección
Token anti-falsificación
Para prevenir ataques CSRF, ASP.NET Core usa tokens de verificación de solicitud. Se crea automáticamente cuando el formulario HTML usa algún atributo asp-* procesado por el TagHelper de ASP.NET Core:
<form asp-action="Configurar">
En otros casos hay que renderizarlo manualmente, o suprimir su validación con el atributo correspondiente cuando no aplica.
Captcha
Decora un método de acción con el atributo de validación de captcha para proteger el endpoint (Google reCAPTCHA); el tag helper de captcha renderiza el widget en la vista. Crono lo usa, por ejemplo, en el formulario de inicio de sesión.
Honeypot
Los honeypots evitan que los robots envíen o manipulen formularios HTML. El HoneypotProtector genera un campo trampa oculto con un token firmado; el ValidarHoneypotAttribute valida la solicitud antes de ejecutar la acción y redirige si detecta un bot; el tag helper honeypot inyecta el campo en la vista. Se usa en los formularios públicos (por ejemplo, la captación de prospectos por QR).
Protección contra sobrecarga
Crono incluye un limitador de tasa por dirección IP para proteger el sistema frente a sobrecargas, habilitable por configuración de forma independiente.