sacg-cronogramas/src/app/guards/access.guard.ts
luis cespedes 6b351ff5b3 Control de acceso basado en funciones
Añade a la aplicación el control de acceso basado en roles mediante guardias.
Introduce guardias de acceso, administración, grupo y rol para la protección de rutas.
Actualiza la barra lateral para incluir elementos de menú basados en roles.
Configura el cliente Keycloak para incluir información de grupo en el token de acceso, habilitando la autorización basada en grupos.
Añade la página de acceso denegado.
2025-05-20 10:42:24 -04:00

65 lines
2.3 KiB
TypeScript

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { DirectAuthService } from '../services/direct-auth.service';
/**
* Guard combinado que verifica si el usuario tiene los roles y/o pertenece a los grupos requeridos
* Espera un array de roles en route.data['roles'] y/o un array de grupos en route.data['groups']
* El parámetro route.data['requireAll'] determina si se requieren todos los roles/grupos o solo alguno
* Si no cumple con los requisitos, redirige a la página de acceso denegado
*/
export const accessGuard: CanActivateFn = (
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean | UrlTree => {
const authService = inject(DirectAuthService);
const router = inject(Router);
// Primero verificar si está autenticado
if (!authService.isAuthenticated()) {
return router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url }
});
}
// Obtener los roles y grupos requeridos del data de la ruta
const requiredRoles = route.data['roles'] as Array<string> || [];
const requiredGroups = route.data['groups'] as Array<string> || [];
const requireAll = route.data['requireAll'] as boolean || false;
// Si no hay roles ni grupos requeridos, permitir acceso
if (requiredRoles.length === 0 && requiredGroups.length === 0) {
return true;
}
// Verificar acceso según la configuración
let hasAccess = false;
if (requireAll) {
// Necesita cumplir TODOS los requisitos
let hasRequiredRoles = true;
let hasRequiredGroups = true;
if (requiredRoles.length > 0) {
hasRequiredRoles = authService.hasAllRoles(requiredRoles);
}
if (requiredGroups.length > 0) {
hasRequiredGroups = authService.inAllGroups(requiredGroups);
}
hasAccess = hasRequiredRoles && hasRequiredGroups;
} else {
// Necesita cumplir ALGUNO de los requisitos
hasAccess = (requiredRoles.length > 0 && authService.hasAnyRole(requiredRoles)) ||
(requiredGroups.length > 0 && authService.inAnyGroup(requiredGroups));
}
if (hasAccess) {
return true;
}
// Si no cumple los requisitos, redirigir a página de acceso denegado
return router.createUrlTree(['/access-denied']);
};