keyclock
This commit is contained in:
parent
c84c9a95c8
commit
1ca16b0e94
@ -1,963 +0,0 @@
|
||||
# Tutorial: Implementación de Keycloak con LDAP para Angular
|
||||
|
||||
Este tutorial explica cómo configurar un sistema de autenticación completo utilizando Keycloak como proveedor de identidad, OpenLDAP como directorio de usuarios y una aplicación Angular que consume estos servicios.
|
||||
|
||||
## Índice
|
||||
|
||||
1. [Preparación del entorno Ubuntu](#1-preparaci%C3%B3n-del-entorno-ubuntu)
|
||||
2. [Instalación y configuración de OpenLDAP](#2-instalaci%C3%B3n-y-configuraci%C3%B3n-de-openldap)
|
||||
3. [Crear estructura LDAP para correos.com](#3-crear-estructura-ldap-para-correoscom)
|
||||
4. [Instalación y configuración de Keycloak](#4-instalaci%C3%B3n-y-configuraci%C3%B3n-de-keycloak)
|
||||
5. [Configuración de Keycloak en la interfaz web](#5-configuraci%C3%B3n-de-keycloak-en-la-interfaz-web)
|
||||
6. [Configuración de una aplicación Angular](#6-configuraci%C3%B3n-de-una-aplicaci%C3%B3n-angular)
|
||||
7. [Arquitectura del sistema](#7-arquitectura-del-sistema)
|
||||
8. [Resolución de problemas comunes](#8-resoluci%C3%B3n-de-problemas-comunes)
|
||||
9. [Verificación y prueba del sistema](#9-verificaci%C3%B3n-y-prueba-del-sistema)
|
||||
10. [Resumen](#10-resumen)
|
||||
|
||||
## 1. Preparación del entorno Ubuntu
|
||||
|
||||
Primero, actualizamos el sistema e instalamos Java:
|
||||
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
sudo apt install openjdk-17-jdk -y
|
||||
|
||||
```
|
||||
|
||||
Verifica la instalación de Java:
|
||||
|
||||
```bash
|
||||
java -version
|
||||
|
||||
```
|
||||
|
||||
## 2. Instalación y configuración de OpenLDAP
|
||||
|
||||
### Instalar OpenLDAP y utilidades
|
||||
|
||||
```bash
|
||||
sudo apt install slapd ldap-utils -y
|
||||
|
||||
```
|
||||
|
||||
Durante la instalación, se te pedirá configurar una contraseña de administrador para LDAP.
|
||||
|
||||
### Reconfigurar LDAP con el dominio correcto
|
||||
|
||||
```bash
|
||||
sudo dpkg-reconfigure slapd
|
||||
|
||||
```
|
||||
|
||||
En la configuración:
|
||||
|
||||
1. "¿Omitir configuración del servidor LDAP?" → No
|
||||
2. "Nombre de dominio DNS:" → **correos.com**
|
||||
3. "Nombre de la organización:" → Correos Org
|
||||
4. "Contraseña de administrador:" → [tu contraseña segura]
|
||||
5. "Confirmar contraseña:" → [repetir la contraseña]
|
||||
6. "Motor de base de datos:" → MDB
|
||||
7. "¿Quiere que se elimine la base de datos cuando se purgue slapd?" → No
|
||||
8. "¿Mover la base de datos antigua?" → Sí
|
||||
|
||||
### Verificar que LDAP se esté ejecutando correctamente
|
||||
|
||||
```bash
|
||||
sudo systemctl status slapd
|
||||
|
||||
```
|
||||
|
||||
### Comprobar la conexión LDAP básica
|
||||
|
||||
```bash
|
||||
ldapsearch -x -H ldap://localhost -b dc=correos,dc=com -D "cn=admin,dc=correos,dc=com" -W
|
||||
|
||||
```
|
||||
|
||||
### Instalar phpLDAPadmin para la gestión gráfica
|
||||
|
||||
```bash
|
||||
sudo apt install phpldapadmin -y
|
||||
|
||||
```
|
||||
|
||||
### Configurar phpLDAPadmin
|
||||
|
||||
Edita el archivo de configuración:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/phpldapadmin/config.php
|
||||
|
||||
```
|
||||
|
||||
Busca y modifica las siguientes líneas:
|
||||
|
||||
```php
|
||||
$servers->setValue('server','host','127.0.0.1');
|
||||
$servers->setValue('server','base',array('dc=correos,dc=com'));
|
||||
$servers->setValue('login','bind_id','cn=admin,dc=correos,dc=com');
|
||||
|
||||
```
|
||||
|
||||
Y cambia esta línea:
|
||||
|
||||
```php
|
||||
$servers->setValue('login','anon_bind',true);
|
||||
|
||||
```
|
||||
|
||||
por:
|
||||
|
||||
```php
|
||||
$servers->setValue('login','anon_bind',false);
|
||||
|
||||
```
|
||||
|
||||
Reinicia el servidor web:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart apache2
|
||||
|
||||
```
|
||||
|
||||
## 3. Crear estructura LDAP para correos.com
|
||||
|
||||
### Crear unidades organizativas
|
||||
|
||||
Crea un archivo para las unidades organizativas:
|
||||
|
||||
```bash
|
||||
nano ~/ou.ldif
|
||||
|
||||
```
|
||||
|
||||
Con el siguiente contenido:
|
||||
|
||||
```ldif
|
||||
dn: ou=grupos,dc=correos,dc=com
|
||||
objectClass: organizationalUnit
|
||||
ou: grupos
|
||||
|
||||
dn: ou=usuarios,dc=correos,dc=com
|
||||
objectClass: organizationalUnit
|
||||
ou: usuarios
|
||||
|
||||
```
|
||||
|
||||
Aplica los cambios:
|
||||
|
||||
```bash
|
||||
ldapadd -x -D cn=admin,dc=correos,dc=com -W -f ~/ou.ldif
|
||||
|
||||
```
|
||||
|
||||
### Crear grupos LDAP
|
||||
|
||||
Crea un archivo para los grupos:
|
||||
|
||||
```bash
|
||||
nano ~/grupos.ldif
|
||||
|
||||
```
|
||||
|
||||
Con el siguiente contenido:
|
||||
|
||||
```ldif
|
||||
dn: cn=administradores,ou=grupos,dc=correos,dc=com
|
||||
objectClass: posixGroup
|
||||
cn: administradores
|
||||
gidNumber: 1000
|
||||
|
||||
dn: cn=desarrolladores,ou=grupos,dc=correos,dc=com
|
||||
objectClass: posixGroup
|
||||
cn: desarrolladores
|
||||
gidNumber: 1001
|
||||
|
||||
dn: cn=usuarios,ou=grupos,dc=correos,dc=com
|
||||
objectClass: posixGroup
|
||||
cn: usuarios
|
||||
gidNumber: 1002
|
||||
|
||||
```
|
||||
|
||||
Aplica los cambios:
|
||||
|
||||
```bash
|
||||
ldapadd -x -D cn=admin,dc=correos,dc=com -W -f ~/grupos.ldif
|
||||
|
||||
```
|
||||
|
||||
### Crear usuarios LDAP
|
||||
|
||||
Primero, genera contraseñas encriptadas para los usuarios:
|
||||
|
||||
```bash
|
||||
slappasswd -s "password123"
|
||||
|
||||
```
|
||||
|
||||
Anota el hash resultante para usarlo en el siguiente archivo.
|
||||
|
||||
Crea un archivo para los usuarios:
|
||||
|
||||
```bash
|
||||
nano ~/usuarios.ldif
|
||||
|
||||
```
|
||||
|
||||
Con el siguiente contenido (reemplazando {HASH} con el hash que generaste):
|
||||
|
||||
```ldif
|
||||
dn: uid=admin,ou=usuarios,dc=correos,dc=com
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: posixAccount
|
||||
objectClass: shadowAccount
|
||||
uid: admin
|
||||
sn: Admin
|
||||
givenName: Admin
|
||||
cn: Admin User
|
||||
displayName: Admin User
|
||||
uidNumber: 1000
|
||||
gidNumber: 1000
|
||||
userPassword: {HASH}
|
||||
loginShell: /bin/bash
|
||||
homeDirectory: /home/admin
|
||||
mail: admin@correos.com
|
||||
|
||||
dn: uid=developer,ou=usuarios,dc=correos,dc=com
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: posixAccount
|
||||
objectClass: shadowAccount
|
||||
uid: developer
|
||||
sn: Developer
|
||||
givenName: Dev
|
||||
cn: Dev User
|
||||
displayName: Developer User
|
||||
uidNumber: 1001
|
||||
gidNumber: 1001
|
||||
userPassword: {HASH}
|
||||
loginShell: /bin/bash
|
||||
homeDirectory: /home/developer
|
||||
mail: developer@correos.com
|
||||
|
||||
dn: uid=user,ou=usuarios,dc=correos,dc=com
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: posixAccount
|
||||
objectClass: shadowAccount
|
||||
uid: user
|
||||
sn: User
|
||||
givenName: Normal
|
||||
cn: Normal User
|
||||
displayName: Normal User
|
||||
uidNumber: 1002
|
||||
gidNumber: 1002
|
||||
userPassword: {HASH}
|
||||
loginShell: /bin/bash
|
||||
homeDirectory: /home/user
|
||||
mail: user@correos.com
|
||||
|
||||
```
|
||||
|
||||
Aplica los cambios:
|
||||
|
||||
```bash
|
||||
ldapadd -x -D cn=admin,dc=correos,dc=com -W -f ~/usuarios.ldif
|
||||
|
||||
```
|
||||
|
||||
### Asociar usuarios a grupos
|
||||
|
||||
Crea un archivo para las membresías:
|
||||
|
||||
```bash
|
||||
nano ~/miembros.ldif
|
||||
|
||||
```
|
||||
|
||||
Con el siguiente contenido:
|
||||
|
||||
```ldif
|
||||
dn: cn=administradores,ou=grupos,dc=correos,dc=com
|
||||
changetype: modify
|
||||
add: memberUid
|
||||
memberUid: admin
|
||||
|
||||
dn: cn=desarrolladores,ou=grupos,dc=correos,dc=com
|
||||
changetype: modify
|
||||
add: memberUid
|
||||
memberUid: developer
|
||||
|
||||
dn: cn=usuarios,ou=grupos,dc=correos,dc=com
|
||||
changetype: modify
|
||||
add: memberUid
|
||||
memberUid: user
|
||||
|
||||
```
|
||||
|
||||
Aplica los cambios:
|
||||
|
||||
```bash
|
||||
ldapmodify -x -D cn=admin,dc=correos,dc=com -W -f ~/miembros.ldif
|
||||
|
||||
```
|
||||
|
||||
### Verificar la estructura LDAP
|
||||
|
||||
```bash
|
||||
ldapsearch -x -H ldap://localhost -b dc=correos,dc=com -D "cn=admin,dc=correos,dc=com" -W
|
||||
|
||||
```
|
||||
|
||||
## 4. Instalación y configuración de Keycloak
|
||||
|
||||
### Descargar e instalar Keycloak
|
||||
|
||||
```bash
|
||||
# Crear directorio para Keycloak
|
||||
mkdir -p ~/keycloak
|
||||
cd ~/keycloak
|
||||
|
||||
# Descargar la última versión de Keycloak
|
||||
wget https://github.com/keycloak/keycloak/releases/download/21.1.1/keycloak-21.1.1.tar.gz
|
||||
|
||||
# Extraer el archivo
|
||||
tar -xvzf keycloak-21.1.1.tar.gz
|
||||
|
||||
# Mover a una ubicación más adecuada
|
||||
sudo mv keycloak-21.1.1 /opt/keycloak
|
||||
|
||||
# Crear un usuario para Keycloak
|
||||
sudo useradd -r -s /sbin/nologin keycloak
|
||||
|
||||
# Asignar permisos
|
||||
sudo chown -R keycloak:keycloak /opt/keycloak
|
||||
|
||||
```
|
||||
|
||||
### Configurar usuario administrador inicial para Keycloak
|
||||
|
||||
Crea un archivo de propiedades:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/keycloak/conf/keycloak.conf
|
||||
|
||||
```
|
||||
|
||||
Agrega estas líneas:
|
||||
|
||||
```
|
||||
# Configuración básica
|
||||
http-port=8080
|
||||
https-port=8443
|
||||
hostname=localhost
|
||||
|
||||
# Configuración de administrador inicial
|
||||
http-enabled=true
|
||||
|
||||
```
|
||||
|
||||
### Iniciar Keycloak en modo desarrollo
|
||||
|
||||
```bash
|
||||
cd /opt/keycloak
|
||||
export KEYCLOAK_ADMIN=admin
|
||||
export KEYCLOAK_ADMIN_PASSWORD=admin
|
||||
sudo -u keycloak bin/kc.sh start-dev
|
||||
|
||||
```
|
||||
|
||||
Esto iniciará Keycloak con un usuario administrador "admin" y contraseña "admin".
|
||||
|
||||
### Configurar Keycloak como servicio
|
||||
|
||||
En otra terminal, crea un archivo de servicio systemd:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/systemd/system/keycloak.service
|
||||
|
||||
```
|
||||
|
||||
Con el siguiente contenido:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Keycloak Application Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=idle
|
||||
User=keycloak
|
||||
Group=keycloak
|
||||
Environment="KEYCLOAK_ADMIN=admin"
|
||||
Environment="KEYCLOAK_ADMIN_PASSWORD=admin"
|
||||
ExecStart=/opt/keycloak/bin/kc.sh start-dev
|
||||
TimeoutStartSec=600
|
||||
TimeoutStopSec=600
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
```
|
||||
|
||||
En el futuro, podrás habilitar e iniciar el servicio con:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable keycloak
|
||||
sudo systemctl start keycloak
|
||||
|
||||
```
|
||||
|
||||
## 5. Configuración de Keycloak en la interfaz web
|
||||
|
||||
Ahora puedes acceder a la consola de administración de Keycloak en http://localhost:8080/admin/ e iniciar sesión con:
|
||||
|
||||
- Usuario: `admin`
|
||||
- Contraseña: `admin`
|
||||
|
||||
### Crear un nuevo Reino (Realm)
|
||||
|
||||
1. Haz clic en el menú desplegable superior izquierdo que dice "master"
|
||||
2. Selecciona "Create Realm"
|
||||
3. Ingresa el nombre: `angular-app`
|
||||
4. Haz clic en "Create"
|
||||
|
||||
### Configurar la Federación de Usuarios LDAP
|
||||
|
||||
1. En el menú lateral izquierdo, selecciona "User Federation"
|
||||
|
||||
2. Haz clic en "Add provider" → "ldap"
|
||||
|
||||
3. Completa los siguientes campos:
|
||||
|
||||
- Console Display Name: `LDAP`
|
||||
- Vendor: `Other`
|
||||
- Connection URL: `ldap://localhost:389`
|
||||
- Enable StartTLS: `OFF`
|
||||
- Bind Type: `simple`
|
||||
- Bind DN: `cn=admin,dc=correos,dc=com`
|
||||
- Bind Credential: (la contraseña de admin LDAP)
|
||||
- Edit Mode: `WRITABLE`
|
||||
- Users DN: `ou=usuarios,dc=correos,dc=com`
|
||||
- Username LDAP attribute: `uid`
|
||||
- RDN LDAP attribute: `uid`
|
||||
- UUID LDAP attribute: `entryUUID`
|
||||
- User Object Classes: `inetOrgPerson, posixAccount`
|
||||
- Custom User LDAP Filter: (dejar en blanco)
|
||||
- Search Scope: `One Level`
|
||||
4. Haz clic en "Test connection" y "Test authentication" para verificar
|
||||
|
||||
5. Guarda la configuración
|
||||
|
||||
6. En la pantalla del proveedor LDAP, ve a la pestaña "Synchronization"
|
||||
|
||||
7. Haz clic en "Sync all users"
|
||||
|
||||
|
||||
### Configurar el Mapeo de Grupos LDAP
|
||||
|
||||
1. En la pantalla del proveedor LDAP, ve a la pestaña "Mappers"
|
||||
2. Haz clic en "Create"
|
||||
3. Completa:
|
||||
- Name: `group-mapper`
|
||||
- Mapper Type: `group-ldap-mapper`
|
||||
- LDAP Groups DN: `ou=grupos,dc=correos,dc=com`
|
||||
- Group Object Classes: `posixGroup`
|
||||
- Membership LDAP Attribute: `memberUid`
|
||||
- Group Name LDAP Attribute: `cn`
|
||||
- User Roles Retrieve Strategy: `LOAD_GROUPS_BY_MEMBER_ATTRIBUTE`
|
||||
- Member-Of LDAP Attribute: `memberOf`
|
||||
- Mapped Group Attributes: (dejar en blanco)
|
||||
- Drop non-existing groups during sync: `ON`
|
||||
4. Haz clic en "Save"
|
||||
5. En la pantalla del mapper, haz clic en "Sync LDAP Groups to Keycloak"
|
||||
|
||||
### Crear un Cliente para Angular
|
||||
|
||||
1. En el menú lateral izquierdo, selecciona "Clients"
|
||||
|
||||
2. Haz clic en "Create client"
|
||||
|
||||
3. Completa:
|
||||
|
||||
- Client type: `OpenID Connect`
|
||||
- Client ID: `angular-app`
|
||||
- Name: `Angular Application`
|
||||
- Haz clic en "Next"
|
||||
4. En la siguiente pantalla:
|
||||
|
||||
- Client authentication: `ON`
|
||||
- Authorization: `OFF`
|
||||
- Haz clic en "Next"
|
||||
5. En la siguiente pantalla:
|
||||
|
||||
- Root URL: `http://localhost:4200`
|
||||
- Home URL: `/`
|
||||
- Valid redirect URIs: `http://localhost:4200/*`
|
||||
- Web origins: `http://localhost:4200`
|
||||
- Haz clic en "Save"
|
||||
6. En la pestaña "Credentials" del cliente, copia el "Client secret" (lo necesitarás para la aplicación Angular)
|
||||
|
||||
|
||||
## 6. Configuración de una aplicación Angular
|
||||
|
||||
Primero, instala Node.js y npm:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
```
|
||||
|
||||
### Crear una aplicación Angular
|
||||
|
||||
```bash
|
||||
# Instalar Angular CLI
|
||||
npm install -g @angular/cli
|
||||
|
||||
# Crear una nueva aplicación
|
||||
ng new angular-keycloak-app
|
||||
cd angular-keycloak-app
|
||||
|
||||
# Instalar la biblioteca para integrar Keycloak
|
||||
npm install keycloak-angular keycloak-js
|
||||
|
||||
```
|
||||
|
||||
### Configurar Keycloak en Angular
|
||||
|
||||
Crea un archivo de configuración en `src/assets/keycloak.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"realm": "angular-app",
|
||||
"auth-server-url": "http://localhost:8080/",
|
||||
"resource": "angular-app",
|
||||
"credentials": {
|
||||
"secret": "TU_CLIENT_SECRET_AQUÍ"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Modifica el archivo `src/app/app.module.ts`:
|
||||
|
||||
```typescript
|
||||
import { NgModule, APP_INITIALIZER } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
function initializeKeycloak(keycloak: KeycloakService) {
|
||||
return () =>
|
||||
keycloak.init({
|
||||
config: {
|
||||
url: 'http://localhost:8080',
|
||||
realm: 'angular-app',
|
||||
clientId: 'angular-app'
|
||||
},
|
||||
initOptions: {
|
||||
onLoad: 'check-sso',
|
||||
silentCheckSsoRedirectUri:
|
||||
window.location.origin + '/assets/silent-check-sso.html'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
KeycloakAngularModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: initializeKeycloak,
|
||||
multi: true,
|
||||
deps: [KeycloakService]
|
||||
}
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
|
||||
```
|
||||
|
||||
Crea un archivo `src/assets/silent-check-sso.html`:
|
||||
|
||||
```html
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
parent.postMessage(location.href, location.origin);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
```
|
||||
|
||||
### Crear un servicio de autenticación
|
||||
|
||||
```bash
|
||||
ng generate service auth
|
||||
|
||||
```
|
||||
|
||||
Edita `src/app/auth.service.ts`:
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@angular/core';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
import { KeycloakProfile } from 'keycloak-js';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthService {
|
||||
|
||||
constructor(private keycloak: KeycloakService) { }
|
||||
|
||||
public getLoggedUser(): Promise<KeycloakProfile | null> {
|
||||
return this.keycloak.loadUserProfile();
|
||||
}
|
||||
|
||||
public login(): void {
|
||||
this.keycloak.login();
|
||||
}
|
||||
|
||||
public logout(): void {
|
||||
this.keycloak.logout();
|
||||
}
|
||||
|
||||
public isLoggedIn(): Promise<boolean> {
|
||||
return this.keycloak.isLoggedIn();
|
||||
}
|
||||
|
||||
public getRoles(): string[] {
|
||||
return this.keycloak.getUserRoles();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Crear un guardia para rutas protegidas
|
||||
|
||||
```bash
|
||||
ng generate guard auth
|
||||
|
||||
```
|
||||
|
||||
Edita `src/app/auth.guard.ts`:
|
||||
|
||||
```typescript
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot, Router, UrlTree } from '@angular/router';
|
||||
import { KeycloakAuthGuard, KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuard extends KeycloakAuthGuard {
|
||||
|
||||
constructor(
|
||||
protected override readonly router: Router,
|
||||
protected readonly keycloak: KeycloakService
|
||||
) {
|
||||
super(router, keycloak);
|
||||
}
|
||||
|
||||
public async isAccessAllowed(
|
||||
route: ActivatedRouteSnapshot,
|
||||
state: RouterStateSnapshot
|
||||
): Promise<boolean | UrlTree> {
|
||||
|
||||
// Verifica si el usuario está autenticado
|
||||
if (!this.authenticated) {
|
||||
await this.keycloak.login({
|
||||
redirectUri: window.location.origin + state.url,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// Obtiene los roles requeridos desde la ruta
|
||||
const requiredRoles = route.data['roles'];
|
||||
|
||||
// Permite el acceso si no hay roles requeridos
|
||||
if (!requiredRoles || requiredRoles.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verifica si el usuario tiene al menos uno de los roles requeridos
|
||||
return requiredRoles.some((role: string) => this.roles.includes(role));
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Configurar las rutas con protección
|
||||
|
||||
Modifica `src/app/app-routing.module.ts`:
|
||||
|
||||
```typescript
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { AuthGuard } from './auth.guard';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: 'admin',
|
||||
component: AppComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: { roles: ['administradores'] }
|
||||
},
|
||||
{
|
||||
path: 'developer',
|
||||
component: AppComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: { roles: ['desarrolladores'] }
|
||||
},
|
||||
{
|
||||
path: 'user',
|
||||
component: AppComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: { roles: ['usuarios'] }
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: AppComponent
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
||||
|
||||
```
|
||||
|
||||
### Modificar el componente principal
|
||||
|
||||
Edita `src/app/app.component.ts`:
|
||||
|
||||
```typescript
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthService } from './auth.service';
|
||||
import { KeycloakProfile } from 'keycloak-js';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
title = 'angular-keycloak-app';
|
||||
isLoggedIn = false;
|
||||
userProfile: KeycloakProfile | null = null;
|
||||
userRoles: string[] = [];
|
||||
|
||||
constructor(private authService: AuthService) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.isLoggedIn = await this.authService.isLoggedIn();
|
||||
|
||||
if (this.isLoggedIn) {
|
||||
this.userProfile = await this.authService.getLoggedUser();
|
||||
this.userRoles = this.authService.getRoles();
|
||||
}
|
||||
}
|
||||
|
||||
login() {
|
||||
this.authService.login();
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.authService.logout();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Edita `src/app/app.component.html`:
|
||||
|
||||
```html
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2>Demo Keycloak con LDAP - Correos.com</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div *ngIf="isLoggedIn; else loginButton">
|
||||
<h3>Bienvenido, {{ userProfile?.firstName }} {{ userProfile?.lastName }}</h3>
|
||||
<p>Email: {{ userProfile?.email }}</p>
|
||||
<p>Nombre de Usuario: {{ userProfile?.username }}</p>
|
||||
|
||||
<h4>Tus Roles:</h4>
|
||||
<ul>
|
||||
<li *ngFor="let role of userRoles">{{ role }}</li>
|
||||
</ul>
|
||||
|
||||
<button class="btn btn-danger" (click)="logout()">Cerrar Sesión</button>
|
||||
</div>
|
||||
|
||||
<ng-template #loginButton>
|
||||
<p>Por favor inicia sesión para acceder al sistema</p>
|
||||
<button class="btn btn-primary" (click)="login()">Iniciar Sesión</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```
|
||||
|
||||
Agrega Bootstrap a `src/index.html`:
|
||||
|
||||
```html
|
||||
<head>
|
||||
<!-- Otras etiquetas -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
```
|
||||
|
||||
### Ejecutar la aplicación
|
||||
|
||||
```bash
|
||||
ng serve
|
||||
|
||||
```
|
||||
|
||||
Abre http://localhost:4200 en tu navegador.
|
||||
|
||||
## 7. Arquitectura del sistema
|
||||
|
||||
La arquitectura del sistema está compuesta por los siguientes componentes:
|
||||
|
||||
- **OpenLDAP**: Directorio de usuarios y grupos (puerto 389)
|
||||
- **phpLDAPadmin**: Interfaz gráfica para administrar LDAP (puerto 80)
|
||||
- **Keycloak**: Servidor de autenticación y autorización (puerto 8080)
|
||||
- **Aplicación Angular**: Cliente que utiliza el SSO de Keycloak (puerto 4200)
|
||||
|
||||
La estructura del directorio LDAP para correos.com es:
|
||||
|
||||
- dc=correos,dc=com (raíz del directorio)
|
||||
- ou=usuarios (unidad organizativa para usuarios)
|
||||
- uid=admin (usuario administrador)
|
||||
- uid=developer (usuario desarrollador)
|
||||
- uid=user (usuario normal)
|
||||
- ou=grupos (unidad organizativa para grupos)
|
||||
- cn=administradores (grupo de administradores)
|
||||
- cn=desarrolladores (grupo de desarrolladores)
|
||||
- cn=usuarios (grupo de usuarios)
|
||||
|
||||
## 8. Resolución de problemas comunes
|
||||
|
||||
### Problema: "ldap_bind: Invalid credentials (49)"
|
||||
|
||||
Este error ocurre cuando intentas conectarte a LDAP con credenciales incorrectas. Para resolverlo:
|
||||
|
||||
1. Verifica que estás usando el dominio correcto: `dc=correos,dc=com`
|
||||
2. Asegúrate de usar el DN correcto: `cn=admin,dc=correos,dc=com`
|
||||
3. Comprueba que la contraseña de administrador es correcta
|
||||
|
||||
Si olvidaste la contraseña, puedes restablecerla:
|
||||
|
||||
```bash
|
||||
sudo dpkg-reconfigure slapd
|
||||
|
||||
```
|
||||
|
||||
O también:
|
||||
|
||||
```bash
|
||||
sudo slappasswd
|
||||
# Copia el hash generado
|
||||
sudo nano /etc/ldap/slapd.d/cn=config/olcDatabase={1}mdb.ldif
|
||||
# Busca olcRootPW y reemplaza el valor con el nuevo hash
|
||||
sudo systemctl restart slapd
|
||||
|
||||
```
|
||||
|
||||
### Problema: No puedes conectarte a LDAP en absoluto
|
||||
|
||||
```bash
|
||||
# Verifica que el servicio esté ejecutándose
|
||||
sudo systemctl status slapd
|
||||
|
||||
# Reinicia el servicio si es necesario
|
||||
sudo systemctl restart slapd
|
||||
|
||||
# Verifica que el puerto esté abierto
|
||||
sudo netstat -tulpn | grep 389
|
||||
|
||||
```
|
||||
|
||||
### Problema: Keycloak no se inicia
|
||||
|
||||
```bash
|
||||
# Verifica los logs
|
||||
sudo journalctl -u keycloak
|
||||
|
||||
# Asegúrate de que Java esté instalado correctamente
|
||||
java -version
|
||||
|
||||
# Verifica los permisos
|
||||
sudo ls -la /opt/keycloak
|
||||
|
||||
```
|
||||
|
||||
### Problema: La aplicación Angular no puede conectarse a Keycloak
|
||||
|
||||
1. Verifica que Keycloak esté en ejecución
|
||||
2. Comprueba la URL del servidor Keycloak en la configuración de Angular
|
||||
3. Asegúrate de que el cliente esté correctamente configurado en Keycloak
|
||||
4. Verifica el Client Secret
|
||||
5. Comprueba las URLs de redirección
|
||||
|
||||
## 9. Verificación y prueba del sistema
|
||||
|
||||
### Verificar que Keycloak esté sincronizando correctamente con LDAP
|
||||
|
||||
1. Inicia sesión en la consola de administración de Keycloak (http://localhost:8080/admin/)
|
||||
2. Navega a "Users" en el reino "angular-app"
|
||||
3. Deberías ver los usuarios de LDAP: admin, developer y user
|
||||
4. Navega a "Groups" y verifica que los grupos de LDAP estén presentes
|
||||
|
||||
### Probar la aplicación Angular
|
||||
|
||||
1. Asegúrate de que Keycloak esté ejecutándose
|
||||
2. Inicia la aplicación Angular con `ng serve`
|
||||
3. Navega a http://localhost:4200
|
||||
4. Haz clic en "Iniciar Sesión"
|
||||
5. Deberías ser redirigido a la pantalla de inicio de sesión de Keycloak
|
||||
6. Inicia sesión con uno de los usuarios LDAP:
|
||||
- Usuario: admin, Contraseña: password123
|
||||
- Usuario: developer, Contraseña: password123
|
||||
- Usuario: user, Contraseña: password123
|
||||
7. Después de iniciar sesión, serás redirigido de vuelta a la aplicación
|
||||
8. La aplicación mostrará tu perfil y roles
|
||||
|
||||
## 10. Resumen
|
||||
|
||||
Esta configuración proporciona un sistema completo de gestión de identidades y acceso con:
|
||||
|
||||
- **Autenticación centralizada**: Los usuarios solo necesitan recordar un conjunto de credenciales
|
||||
- **Gestión de usuarios unificada**: Todos los usuarios se administran en LDAP
|
||||
- **Control de acceso basado en roles**: Las rutas y funcionalidades pueden ser protegidas según los roles del usuario
|
||||
- **Experiencia de inicio de sesión único (SSO)**: Una vez autenticado, el usuario puede acceder a todas las aplicaciones integradas
|
||||
|
||||
Este sistema es adecuado para entornos empresariales donde se requiere un control de acceso detallado y una gestión centralizada de usuarios.
|
||||
|
||||
La implementación es nativa en un sistema Ubuntu, lo que la hace ideal para despliegues en servidores VPS o entornos similares sin necesidad de contenedores.
|
||||
1476
tutorial-keycloak-completo.md
Normal file
1476
tutorial-keycloak-completo.md
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user