Instalación de Keycloak para Single Sign-On
Keycloak es la plataforma de gestión de identidades y acceso (IAM) open source más utilizada para implementar Single Sign-On (SSO) en aplicaciones modernas. Con soporte para OAuth2, OpenID Connect, SAML 2.0 y federación de identidades con LDAP o Active Directory, Keycloak centraliza la autenticación de múltiples aplicaciones en un único servidor. Esta guía cubre la instalación con Docker, la configuración de realms, clientes, OAuth2/OIDC y la integración con aplicaciones web.
Requisitos Previos
- Servidor Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
- Docker y Docker Compose instalados (para el método Docker)
- Java 17+ (para instalación nativa)
- Al menos 2 GB de RAM (4 GB recomendado en producción)
- PostgreSQL (recomendado para producción en lugar de H2)
- Dominio con SSL configurado
Instalación con Docker
Docker Compose con PostgreSQL
mkdir -p /opt/keycloak
cd /opt/keycloak
# /opt/keycloak/docker-compose.yml
services:
postgres:
image: postgres:15
container_name: keycloak-postgres
restart: unless-stopped
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: clave-postgres-segura
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- keycloak-net
keycloak:
image: quay.io/keycloak/keycloak:24.0.3
container_name: keycloak
restart: unless-stopped
depends_on:
- postgres
environment:
# Credenciales del administrador inicial
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: cambia-esta-clave-admin
# Configuración de la base de datos
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: clave-postgres-segura
# URL pública del servidor (importante para los redirects OAuth2)
KC_HOSTNAME: sso.tudominio.com
KC_HOSTNAME_STRICT: "false"
# Proxy inverso
KC_PROXY: edge
KC_HTTP_ENABLED: "true"
ports:
- "8080:8080"
command: start
networks:
- keycloak-net
volumes:
postgres-data:
networks:
keycloak-net:
driver: bridge
# Iniciar Keycloak
docker compose up -d
# Ver los logs
docker compose logs -f keycloak
# Esperar hasta ver el mensaje: "Keycloak 24.0.3 on JVM (powered by Quarkus)"
# La interfaz web estará disponible en: http://IP_SERVIDOR:8080
Instalación Nativa (JAR)
# Instalar Java 17
sudo apt-get update
sudo apt-get install -y openjdk-17-jdk
# Descargar Keycloak
wget https://github.com/keycloak/keycloak/releases/download/24.0.3/keycloak-24.0.3.tar.gz
tar -xzf keycloak-24.0.3.tar.gz -C /opt/
ln -s /opt/keycloak-24.0.3 /opt/keycloak
# Crear el usuario del sistema
sudo useradd -r -s /bin/false keycloak
sudo chown -R keycloak:keycloak /opt/keycloak-24.0.3 /opt/keycloak
# Configurar las variables de entorno
cat > /opt/keycloak/conf/keycloak.conf << 'EOF'
# Base de datos
db=postgres
db-url=jdbc:postgresql://localhost:5432/keycloak
db-username=keycloak
db-password=clave-postgres-segura
# Hostname
hostname=sso.tudominio.com
hostname-strict=false
# Proxy
proxy=edge
http-enabled=true
http-port=8080
EOF
# Crear el servicio systemd
sudo cat > /etc/systemd/system/keycloak.service << 'EOF'
[Unit]
Description=Keycloak SSO Server
After=network.target postgresql.service
[Service]
User=keycloak
Group=keycloak
WorkingDirectory=/opt/keycloak
Environment=KEYCLOAK_ADMIN=admin
Environment=KEYCLOAK_ADMIN_PASSWORD=cambia-esta-clave-admin
ExecStart=/opt/keycloak/bin/kc.sh start
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable keycloak
sudo systemctl start keycloak
Configuración de Realms
Un realm es un espacio de nombres aislado que contiene usuarios, grupos, roles y aplicaciones. El realm master es para la administración de Keycloak y no debe usarse para aplicaciones.
Crear un realm para la organización
- Accede a la consola:
https://sso.tudominio.com - Haz clic en master en la esquina superior izquierda
- Selecciona Create Realm
- Configura:
- Realm name:
empresa(o el nombre de tu organización) - Enabled: ON
- Realm name:
Configuración del realm mediante API
# Obtener el token de acceso del admin
TOKEN=$(curl -s -X POST "http://localhost:8080/realms/master/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=TU_CLAVE_ADMIN&grant_type=password&client_id=admin-cli" | \
python3 -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
# Crear un nuevo realm via API REST
curl -X POST "http://localhost:8080/admin/realms" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"realm": "empresa",
"enabled": true,
"displayName": "Mi Empresa",
"registrationAllowed": false,
"resetPasswordAllowed": true,
"loginWithEmailAllowed": true,
"ssoSessionMaxLifespan": 36000,
"accessTokenLifespan": 300
}'
Gestión de Clientes OAuth2/OIDC
Un "client" en Keycloak representa una aplicación que delega la autenticación.
Crear un cliente para una aplicación web
- En el realm
empresa, ve a Clients > Create client - Configura:
- Client type: OpenID Connect
- Client ID:
mi-aplicacion - Client authentication: ON (para apps con backend)
- En la siguiente pantalla:
- Valid redirect URIs:
https://app.tudominio.com/* - Web origins:
https://app.tudominio.com
- Valid redirect URIs:
Crear cliente via CLI (kcadm.sh)
# Autenticar con kcadm
/opt/keycloak/bin/kcadm.sh config credentials \
--server http://localhost:8080 \
--realm master \
--user admin \
--password TU_CLAVE_ADMIN
# Crear el cliente
/opt/keycloak/bin/kcadm.sh create clients \
-r empresa \
-s clientId=mi-aplicacion \
-s "name=Mi Aplicación Web" \
-s protocol=openid-connect \
-s publicClient=false \
-s standardFlowEnabled=true \
-s serviceAccountsEnabled=true \
-s "redirectUris=[\"https://app.tudominio.com/*\"]" \
-s "webOrigins=[\"https://app.tudominio.com\"]"
Obtener el Client Secret
# Via API
curl -s "http://localhost:8080/admin/realms/empresa/clients/{CLIENT_ID}/client-secret" \
-H "Authorization: Bearer $TOKEN" | python3 -m json.tool
Flujo OAuth2 Authorization Code
# 1. Redirigir al usuario a la URL de autorización:
# https://sso.tudominio.com/realms/empresa/protocol/openid-connect/auth?
# client_id=mi-aplicacion&
# redirect_uri=https://app.tudominio.com/callback&
# response_type=code&
# scope=openid profile email
# 2. Intercambiar el código por un token
curl -X POST "https://sso.tudominio.com/realms/empresa/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=mi-aplicacion" \
-d "client_secret=TU_CLIENT_SECRET" \
-d "code=CODIGO_RECIBIDO" \
-d "redirect_uri=https://app.tudominio.com/callback"
# 3. Obtener información del usuario
curl "https://sso.tudominio.com/realms/empresa/protocol/openid-connect/userinfo" \
-H "Authorization: Bearer ACCESS_TOKEN"
Federación de Usuarios con LDAP
# Configurar la federación con OpenLDAP o Active Directory
# En el realm empresa: User Federation > Add provider > LDAP
Configuración para OpenLDAP:
- Vendor: Other
- Connection URL:
ldap://ldap.empresa.com:389 - Users DN:
ou=usuarios,dc=empresa,dc=com - Bind DN:
cn=admin,dc=empresa,dc=com - Bind Credential: contraseña del admin LDAP
- Edit Mode: READ_ONLY (para no modificar el LDAP)
- Sync mode: Force
# Probar la conexión LDAP desde la interfaz
# User Federation > Tu proveedor LDAP > Test connection
# User Federation > Tu proveedor LDAP > Test authentication
# Sincronizar todos los usuarios de LDAP
# User Federation > Tu proveedor LDAP > Sync all users
Configuración de SAML
Para integraciones con aplicaciones empresariales que usan SAML 2.0:
# Crear un cliente SAML
/opt/keycloak/bin/kcadm.sh create clients \
-r empresa \
-s clientId=https://app-saml.tudominio.com/saml \
-s protocol=saml \
-s "attributes.saml_assertion_consumer_url_post=https://app-saml.tudominio.com/saml/acs" \
-s "attributes.saml.signing.certificate=CERTIFICADO_BASE64"
# Descargar los metadatos SAML del Identity Provider
curl -o idp-metadata.xml \
"https://sso.tudominio.com/realms/empresa/protocol/saml/descriptor"
Proxy Inverso con Nginx
# /etc/nginx/sites-available/keycloak
server {
listen 80;
server_name sso.tudominio.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name sso.tudominio.com;
ssl_certificate /etc/letsencrypt/live/sso.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sso.tudominio.com/privkey.pem;
client_max_body_size 10M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
sudo certbot --nginx -d sso.tudominio.com
sudo ln -s /etc/nginx/sites-available/keycloak /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Solución de Problemas
Keycloak no inicia y los logs muestran errores de base de datos
# Verificar que PostgreSQL está activo y accesible
sudo systemctl status postgresql
psql -U keycloak -d keycloak -h localhost -c "SELECT 1;"
# Ver los logs de Keycloak
docker compose logs keycloak --tail 50
# O para instalación nativa:
sudo journalctl -u keycloak -n 50
Los redirects OAuth2 dan error
# Verificar que KC_HOSTNAME coincide con la URL pública
# El Client debe tener las URIs de redirect correctas configuradas
# Probar el endpoint de descubrimiento OIDC
curl https://sso.tudominio.com/realms/empresa/.well-known/openid-configuration
Keycloak detrás de Nginx muestra URLs con http en lugar de https
# Verificar que KC_PROXY=edge está configurado
# Y que Nginx envía el header X-Forwarded-Proto: https
grep -i "forwarded-proto" /etc/nginx/sites-available/keycloak
Alto consumo de memoria
# Ajustar la memoria de la JVM en Docker
# Añadir al docker-compose.yml en la sección environment:
KC_JAVA_OPTS: "-Xms512m -Xmx1024m"
Conclusión
Keycloak transforma la gestión de autenticación en una infraestructura dispersa en un sistema centralizado y estandarizado. Con un único servidor de SSO, todas las aplicaciones de la organización pueden delegar la autenticación, ofrecer inicio de sesión social, integrarse con el LDAP corporativo y gestionar roles y permisos de forma consistente. La compatibilidad con OAuth2, OIDC y SAML garantiza que cualquier aplicación moderna puede integrarse con mínimo esfuerzo de desarrollo.


