Login alojado (Universal Login)
El problema: ¿dónde debe vivir el formulario de inicio de sesión?
Toda aplicación que autentica usuarios debe decidir dónde vive el formulario de inicio de sesión. Existen tres enfoques fundamentales, y la elección tiene profundas implicaciones de seguridad.
Login incrustado (el enfoque arriesgado)
La aplicación renderiza su propio formulario de inicio de sesión y recoge las credenciales directamente. El JavaScript de tu aplicación puede leer los campos del formulario, interceptar pulsaciones de teclas y acceder a las credenciales.
Login alojado (el enfoque seguro)
Las credenciales se introducen en un origen diferente — controlado completamente por el proveedor de identidad. El JavaScript de tu aplicación no puede leer los campos del formulario, interceptar pulsaciones de teclas ni acceder a las credenciales de ninguna forma. La política de mismo origen del navegador aplica este límite automáticamente.
| Riesgo | Login incrustado | Login alojado |
|---|---|---|
| XSS roba credenciales | Sí — tu JS puede leer el campo de contraseña | No — origen diferente, tu JS no puede acceder a él |
| Script de terceros lee credenciales | Sí — cualquier script en tu bundle se ejecuta en el mismo origen | No — los scripts de terceros en tu origen no pueden alcanzar la página de autenticación |
| Phishing de credenciales via manipulación DOM | Sí — un atacante puede modificar tu formulario de login | No — la página de login está en el dominio del IdP |
| Ámbito de autocompletado del gestor de contraseñas | Tu dominio | El dominio del IdP (consistente entre todas las apps) |
| Aplicación de MFA | Debes implementarlo | El IdP lo gestiona de forma transparente |
| Integración de social login | Debes integrar cada proveedor | El IdP presenta todos los proveedores configurados |
| Ámbito de auditoría de conformidad | Toda tu aplicación | Solo las páginas de login del IdP |
El Login Alojado es el enfoque recomendado por el OAuth 2.0 Security Best Current Practice (RFC 6819). Auth0 lo llama “Universal Login”, Okta lo llama “Okta-hosted Sign-In” y Auris lo llama “Hosted Login”. El principio de seguridad es el mismo: nunca dejes que tu aplicación toque las credenciales sin procesar.
Cómo funciona: el flujo completo
El Login Alojado de Auris implementa el flujo OAuth2 Authorization Code con PKCE (RFC 7636). Aquí está la secuencia completa, paso a paso:
- Tu aplicación genera un code verifier y un code challenge (PKCE S256)
- El navegador es redirigido a la página de login alojada de Auris con el code challenge
- Auris almacena el code challenge en una
OAuthSessionde servidor - El usuario introduce credenciales, completa el MFA si es necesario
- Auris valida las credenciales contra Keycloak
- Si la autenticación es exitosa, el motor de Actions ejecuta los hooks post-login
- Auris redirige de vuelta a tu app con un código de autorización de un solo uso
- Tu app intercambia el código + code verifier por tokens
- Auris verifica que
SHA256(code_verifier) === stored_code_challenge - Se emiten access token, refresh token e ID token
Gestión de sesiones
Auris utiliza dos modelos del lado del servidor para gestionar el flujo de login alojado:
OAuthSession
Una OAuthSession es una sesión de flujo temporal que existe durante la redirección de autorización. Se crea en el paso 1 y se destruye en el paso 8.
| Campo | Propósito |
|---|---|
state | Token CSRF para validar la redirección |
codeChallenge | El hash PKCE para verificación posterior |
redirectUri | El redirect_uri registrado |
scope | Los scopes solicitados |
expiresAt | TTL de 10 minutos — los flujos incompletos se limpian automáticamente |
UserSession
Una UserSession se crea después de la autenticación exitosa y persiste durante toda la sesión del usuario. Contiene el access token actual, refresh token, familia de tokens y metadatos del dispositivo.
Pipeline de seguridad
Cada intento de login pasa por un pipeline de seguridad completo:
- Validación de parámetros: state, code_challenge, redirect_uri, client_id
- Verificación de credenciales: contraseña, magic link, OTP, WebAuthn, social token
- Puntuación de riesgo adaptativo: IP, dispositivo, geo, comportamiento
- Evaluación de MFA: ¿se requiere un factor adicional según la política y la puntuación de riesgo?
- Motor de Actions: ejecuta los hooks post-autenticación del tenant
- Emisión de tokens: genera access token con claims, incluyendo los custom claims configurados
El motor de Actions puede rechazar el login devolviendo { success: false } desde un hook. Esto permite que los tenants implementen lógica de bloqueo personalizada — por ejemplo, bloquear usuarios de ciertos países o sin un atributo de perfil requerido.