
Asegurando tu Aplicación Angular: Una Guía Completa para la Integración con Keycloak
Tabla de Contenidos
Tabla de Contenidos
Una de las partes repetitivas, complejas e importantes de una aplicación es la autorización y autenticación de usuarios. Hay muchas herramientas para esto, como Firebase, Auth0 y Okta, o puedes permitir que los usuarios inicien sesión con proveedores de terceros como Gmail, Microsoft o redes sociales.
He usado Keycloak en aplicaciones web antes y me gusta la idea de centralizar la autenticación y autorización. Esto nos permite enfocarnos en desarrollar nuestra aplicación. En esta guía, te mostraré cómo configurar Keycloak con una aplicación Angular simple para gestionar usuarios.
Pero, ¿qué puede hacer Keycloak por mí?
Keycloak es una herramienta de código abierto que facilita la autenticación y autorización en aplicaciones y servicios. Ayuda a gestionar usuarios e incluye características como inicio de sesión único (SSO), federación de identidades y gestión de roles y permisos.
En términos simples, Keycloak te ayuda a:
• Autenticar Usuarios: Permitir que los usuarios inicien sesión en tu aplicación de forma segura.
• Autorización: Controla qué partes de tu aplicación pueden acceder los usuarios según sus roles y permisos.
• Federación de Identidades: Se conecta con múltiples proveedores de identidad (como Google, Facebook, etc.) para que los usuarios puedan iniciar sesión con sus cuentas existentes.
• Gestión de Sesiones: Maneja las sesiones de usuario, incluido el cierre de sesión global y la expiración de sesiones.
Proyecto en funcionamiento
Este es el resultado final de la siguiente guía.
Parte 1. Ejecutar Keycloak con Docker Compose
Primero, configuremos Keycloak usando Docker Compose. Crea un archivo docker-compose.yml con el siguiente contenido:
// docker-compose.yml
version: '3.8'
services:
keycloak:
image: quay.io/keycloak/keycloak:23.0.4
container_name: keycloak
ports:
- "8080:8080"
environment:
- KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN}
- KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD}
- KC_DB=${KC_DB}
- KC_DB_URL=${KC_DB_URL}
- KC_DB_USERNAME=${POSTGRES_USER}
- KC_DB_PASSWORD=${POSTGRES_PASSWORD}
- KC_HOSTNAME=${KC_HOSTNAME}
command: [ "start-dev", "--import-realm" ]
postgres:
image: postgres:latest
container_name: postgres
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Y, un archivo .env al mismo nivel que el docker-compose.yml:
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin
KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
KC_HOSTNAME=localhost
KC_DB=postgres
POSTGRES_DB=keycloak
POSTGRES_USER=keycloak
POSTGRES_PASSWORD=password
Ahora, puedes ir a tu terminal y hacer docker compose up y ahora tienes un Keycloak funcionando.

Ahora, podemos acceder a nuestro Keycloak usando http://localhost:8080 y configurar nuestro nuevo cliente para nuestra aplicación Angular.

Haciendo clic en Administration Console usando la contraseña agregada en el archivo .env (en nuestro caso es usuario: admin, contraseña: admin)

Configuración de Keycloak
Crear un realm: En Keycloak, un realm es un espacio aislado que contiene todo lo necesario para gestionar la autenticación y autorización para un conjunto de aplicaciones o servicios. Puedes definir usuarios, roles, clientes, identidades y configuraciones de seguridad dentro de un realm.

Crear un cliente: Un cliente representa una aplicación o servicio que usa Keycloak para gestionar la autenticación y autorización. Los clientes pueden ser aplicaciones web, aplicaciones móviles, servicios backend o cualquier otra entidad que necesite autenticar usuarios y gestionar sus permisos. Nuestra aplicación angular será un cliente de Keycloak.
Paso 1: Configuración general:

Paso 2: Configuración de capacidad: Lo dejamos tal como está, en nuestra demostración básica, no necesitamos cambiar/agregar nada.

Paso 3: Configuración de inicio de sesión: Esta es importante, vamos a explicar cada entrada:
Root URL: La URL raíz de nuestra aplicación, Keycloak usa esta URL como base para la redirección después de la autenticación.
Home URL: Puede ser usada por Keycloak para redirigir a los usuarios a la página principal de tu aplicación después de la autenticación, ej.,
http://localhost:8080/dashboardValid redirect URIs: Especifica las URLs a las que Keycloak puede redirigir después de una autenticación exitosa. Esto es crucial para prevenir ataques de redirección maliciosos.
Valid post-logout redirect URIs: Define las URLs a las que Keycloak puede redirigir después de cerrar sesión. Esto asegura que los usuarios sean redirigidos a un lugar seguro y esperado después de salir de la aplicación.
Web origins: Define qué orígenes están permitidos para hacer solicitudes de origen cruzado a Keycloak. Esto es esencial para que tu aplicación Angular se comunique con Keycloak sin ser bloqueada debido a las políticas CORS.

Crear un usuario de prueba para el inicio de sesión
Para nuestra Demo de Angular App, necesitamos crear un usuario. Ve a Users y agrega un nuevo usuario dentro del realm que creamos.

Después de crearlo, podemos agregar una contraseña:

Y eso es todo. Ahora estamos listos para enfocarnos en nuestra aplicación Angular.
Parte 2. Integrar Keycloak con Angular
Asumiendo que ya tenemos una aplicación Angular (Angular 18), necesitamos instalar estas 2 bibliotecas: keycloak-js y keycloak-angular:
npm install keycloak-js keycloak-angular
// OR
yarn add keycloak-js keycloak-angular
Lo que agregaremos a nuestra aplicación Angular
- Agregar la configuración de Keycloak a nuestro archivo environment.ts para usarlo desde allí.
// environment.development.ts
export const environment = {
production: false,
keycloak: {
authority: 'http://localhost:8080', // Keycloak server
redirectUri: 'http://localhost:4200', // redirect
postLogoutRedirectUri: 'http://localhost:4200/logout', // post logout url
realm: 'my-app',
clientId: 'angular-app',
}
};
- Inicializar el cliente de Keycloak y registrarlo en
APP_INITIALIZER
// keycloak.factory.ts
import { KeycloakService } from 'keycloak-angular';
import { environment } from '../../environments/environment';
/**
* Initializes Keycloak service.
* @param {KeycloakService} keycloak - The Keycloak service instance.
*/
export function initializeKeycloak(keycloak: KeycloakService) {
return async () => keycloak.init({
config: {
url: environment.keycloak.authority,
realm: environment.keycloak.realm,
clientId: environment.keycloak.clientId,
},
loadUserProfileAtStartUp: true,
initOptions: {
onLoad: 'check-sso',
silentCheckSsoRedirectUri:
window.location.origin + '/silent-check-sso.html',
checkLoginIframe: false,
redirectUri: environment.keycloak.redirectUri,
},
});
}
Y registrar como factory en appConfig con el token APP_INITIALIZER
// app.config.ts
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(appRoutes),
{
provide: APP_INITIALIZER,
useFactory: initializeKeycloak, // Nuestra factory
multi: true,
deps: [KeycloakService],
},
KeycloakService
],
};
- Crear el archivo HTML (
silent-check-sso.html) para la verificación silenciosa de SSO
<html>
<body>
<script>
parent.postMessage(location.href, location.origin);
</script>
</body>
</html>
Este archivo es importante para asegurar que todo funcione correctamente. Asegúrate de que sea accesible. En mi caso, lo coloqué dentro de /public/. Verifica dónde está ubicada tu carpeta de assets en angular.json o project.json (si estás usando Nx). Para verificar si es accesible http://localhost:4200/silent-check-sso.html en mi caso.
- Servicio de autenticación para usar
KeycloakService
// auth.service.ts
/**
* Provides authentication services using Keycloak.
*
*/
@Injectable({
providedIn: 'root'
})
export class AuthService {
readonly #keycloakService = inject(KeycloakService);
/**
* Redirects the user to the login page.
*
* @returns {Promise<void>} A promise that resolves when the user is redirected to the login page.
*/
redirectToLoginPage(): Promise<void> {
return this.#keycloakService.login();
}
/**
* Retrieves the username of the currently authenticated user.
*
* @return {string} The username of the authenticated user.
*/
get userName(): string {
return this.#keycloakService.getUsername();
}
/**
* Checks if the user is currently logged in.
*
* @return {boolean} - Returns true if the user is logged in, otherwise returns false.
*/
isLoggedIn(): boolean {
return this.#keycloakService.isLoggedIn();
}
/**
* Logs out the user from the Keycloak service.
*
* @return {void} This method does not return any value.
*/
logout(): void {
this.#keycloakService.logout(environment.keycloak.postLogoutRedirectUri);
}
}
- Crear un auth guard para evitar que los usuarios visiten rutas protegidas
// auth.guard.ts
export const authGuard: CanActivateFn = () => {
const authService = inject(AuthService);
// Checks if the user is currently logged in.
if (authService.isLoggedIn()) {
// Allow go to the URL
return true;
}
// Redirects the user to the login page.
authService.redirectToLoginPage();
return false;
};
- Usar el authGuard en nuestro archivo
appRoutes:
export const appRoutes: Route[] = [
{
path: '',
pathMatch: 'full',
component: MainPageComponent,
},
{
path: 'public',
component: PublicPageComponent,
},
{
path: 'private',
canActivate: [authGuard], // <-- solo usuarios autenticados
component: PrivatePageComponent,
},
{
path: 'logout',
component: LogoutComponent,
},
{
path: '404',
component: NotFoundComponent,
},
{
path: '**',
redirectTo: '404',
},
];
Páginas para verificar el flujo de la aplicación
MainPageComponent: Con una página de bienvenida, que mostrará las rutas disponibles para acceder y un botón de Login que nos redirige a Keycloak para la autenticación. [github]
PrivatePageComponent: Está protegida por el authGuard que creamos. Si no has iniciado sesión, te envía a la página de inicio de sesión. [github]
PublicPageComponent: Es accesible para cualquier persona, ya sea que haya iniciado sesión o no. [github]
LogoutComponent: Esto informa al usuario que ha cerrado sesión. [github]
Esta es la URL del repositorio del proyecto funcionando si quieres descargar y ejecutar todo junto.
Conclusión
Integrar Keycloak con tu aplicación Angular te brinda una forma robusta de manejar la autenticación y autorización. Keycloak se encarga de la seguridad, para que puedas enfocarte en construir tu aplicación. Ofrece características como inicio de sesión único, federación de identidades y control de acceso basado en roles, haciendo que la experiencia del usuario sea segura y fluida.


