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.
65 lines
2.3 KiB
TypeScript
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']);
|
|
}; |