From 89e97a3634393170e4f1c016561b3a8f2dfddf5a Mon Sep 17 00:00:00 2001 From: luis cespedes Date: Thu, 22 May 2025 09:52:40 -0400 Subject: [PATCH] guardias --- src/app/guards/access.guard.ts | 99 ++++++++++++++++----------------- src/app/guards/admin.guard.ts | 39 ++++++------- src/app/guards/auth.guard.ts | 9 +-- src/app/guards/group.guard.ts | 55 +++++++++--------- src/app/guards/role.guard.ts | 15 ++--- src/environments/environment.ts | 2 +- tutorial-keycloak-completo.md | 4 +- 7 files changed, 105 insertions(+), 118 deletions(-) diff --git a/src/app/guards/access.guard.ts b/src/app/guards/access.guard.ts index 170e7c1..dcc9b75 100644 --- a/src/app/guards/access.guard.ts +++ b/src/app/guards/access.guard.ts @@ -9,57 +9,54 @@ import { DirectAuthService } from '../services/direct-auth.service'; * 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 || []; - const requiredGroups = route.data['groups'] as Array || []; - 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); +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 } + }); } - - if (requiredGroups.length > 0) { - hasRequiredGroups = authService.inAllGroups(requiredGroups); + + // Obtener los roles y grupos requeridos del data de la ruta + const requiredRoles = route.data['roles'] as Array || []; + const requiredGroups = route.data['groups'] as Array || []; + 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; } - - 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']); + + // 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']); }; \ No newline at end of file diff --git a/src/app/guards/admin.guard.ts b/src/app/guards/admin.guard.ts index 4d30112..02159de 100644 --- a/src/app/guards/admin.guard.ts +++ b/src/app/guards/admin.guard.ts @@ -7,25 +7,22 @@ import { DirectAuthService } from '../services/direct-auth.service'; * Guard que verifica si el usuario es administrador * Si no es administrador, redirige a la página de acceso denegado */ -export const adminGuard: 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 } - }); - } - - // Verificar si es administrador - if (authService.isAdmin()) { - return true; - } - - // Si no es administrador, redirigir a página de acceso denegado - return router.createUrlTree(['/access-denied']); +export const adminGuard: 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 } + }); + } + + // Verificar si es administrador + if (authService.isAdmin()) { + return true; + } + + // Si no es administrador, redirigir a página de acceso denegado + return router.createUrlTree(['/access-denied']); }; \ No newline at end of file diff --git a/src/app/guards/auth.guard.ts b/src/app/guards/auth.guard.ts index 574b71d..98629de 100644 --- a/src/app/guards/auth.guard.ts +++ b/src/app/guards/auth.guard.ts @@ -7,10 +7,7 @@ import { DirectAuthService } from '../services/direct-auth.service'; * Guard que verifica si el usuario está autenticado * Si el usuario no está autenticado, redirige al login con la URL de retorno */ -export const authGuard: CanActivateFn = ( - route: ActivatedRouteSnapshot, - state: RouterStateSnapshot -): boolean | UrlTree => { +export const authGuard: CanActivateFn = (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree => { const authService = inject(DirectAuthService); const router = inject(Router); @@ -19,7 +16,7 @@ export const authGuard: CanActivateFn = ( } // Si no está autenticado, redirigir a login con la URL de retorno - return router.createUrlTree(['/login'], { - queryParams: { returnUrl: state.url } + return router.createUrlTree(['/login'], { + queryParams: { returnUrl: state.url } }); }; \ No newline at end of file diff --git a/src/app/guards/group.guard.ts b/src/app/guards/group.guard.ts index 2439cbe..187e814 100644 --- a/src/app/guards/group.guard.ts +++ b/src/app/guards/group.guard.ts @@ -8,33 +8,30 @@ import { DirectAuthService } from '../services/direct-auth.service'; * Espera un array de grupos en route.data['groups'] * Si no pertenece a los grupos necesarios, redirige a la página de acceso denegado */ -export const groupGuard: 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 grupos requeridos del data de la ruta - const requiredGroups = route.data['groups'] as Array; - - // Si no hay grupos requeridos, permitir acceso - if (!requiredGroups || requiredGroups.length === 0) { - return true; - } - - // Usar la función de servicio para verificar grupos - if (authService.inAnyGroup(requiredGroups)) { - return true; - } - - // Si no pertenece a los grupos necesarios, redirigir a página de acceso denegado - return router.createUrlTree(['/access-denied']); +export const groupGuard: 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 grupos requeridos del data de la ruta + const requiredGroups = route.data['groups'] as Array; + + // Si no hay grupos requeridos, permitir acceso + if (!requiredGroups || requiredGroups.length === 0) { + return true; + } + + // Usar la función de servicio para verificar grupos + if (authService.inAnyGroup(requiredGroups)) { + return true; + } + + // Si no pertenece a los grupos necesarios, redirigir a página de acceso denegado + return router.createUrlTree(['/access-denied']); }; \ No newline at end of file diff --git a/src/app/guards/role.guard.ts b/src/app/guards/role.guard.ts index a11a4ca..be3def9 100644 --- a/src/app/guards/role.guard.ts +++ b/src/app/guards/role.guard.ts @@ -8,33 +8,30 @@ import { DirectAuthService } from '../services/direct-auth.service'; * Espera un array de roles en route.data['roles'] * Si no tiene los roles necesarios, redirige a la página de acceso denegado */ -export const roleGuard: CanActivateFn = ( - route: ActivatedRouteSnapshot, - state: RouterStateSnapshot -): boolean | UrlTree => { +export const roleGuard: 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 requeridos del data de la ruta const requiredRoles = route.data['roles'] as Array; - + // Si no hay roles requeridos, permitir acceso if (!requiredRoles || requiredRoles.length === 0) { return true; } - + // Usar la función de servicio para verificar roles if (authService.hasAnyRole(requiredRoles)) { return true; } - + // Si no tiene los roles necesarios, redirigir a página de acceso denegado return router.createUrlTree(['/access-denied']); }; \ No newline at end of file diff --git a/src/environments/environment.ts b/src/environments/environment.ts index b3ed113..baf7211 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -21,6 +21,6 @@ export const environment = { // Intervalo de log en milisegundos (1 segundo) logInterval: 2000, // Habilitar logs de inactividad - enableActivityLogs: true + enableActivityLogs: false } }; \ No newline at end of file diff --git a/tutorial-keycloak-completo.md b/tutorial-keycloak-completo.md index bebd37f..dd4fea1 100644 --- a/tutorial-keycloak-completo.md +++ b/tutorial-keycloak-completo.md @@ -735,7 +735,9 @@ Alternativamente, puedes crear un mapper de tipo "User Attribute" si prefieres a ![configuracion maper](https://i.ibb.co/TqWHYYjX/imagen.png) -¿Qué logramos con esto? Fácil: que en el access token aparezcan los grupos a los que pertenece el usuario, tal cual los configuramos en LDAP. Esto puede ayudar para crear políticas de acceso a páginas o rutas protegidas para algún grupo en específico más adelante. ![ejemplo json acces token ](https://i.ibb.co/jPrR0XH3/imagen.png) +¿Qué logramos con esto? Fácil: que en el access token aparezcan los grupos a los que pertenece el usuario, tal cual los configuramos en LDAP. Esto puede ayudar para crear políticas de acceso a páginas o rutas protegidas para algún grupo en específico más adelante. + +![ejemplo json acces token ](https://i.ibb.co/jPrR0XH3/imagen.png) ## 11. Arquitectura del sistema