2FA y sesiones¶
Mecanismos de autenticación reforzada y gestión de sesiones activas.
2FA — Two-Factor Authentication¶
Eval360Pro implementa 2FA via TOTP (Time-based One-Time Password) compatible con apps autenticadoras estándar:
- Google Authenticator
- Microsoft Authenticator
- 1Password
- Authy
- Bitwarden Authenticator
- Cualquier app que soporte el estándar
otpauth://totp/...
Activación (cualquier usuario, sobre su propia cuenta)¶
- Mi perfil (menú superior derecho) → tab Autenticación de dos factores
- Ver código QR en pantalla
- Abrir la app autenticadora del celular → "Agregar cuenta" → escanear QR
- (Alternativa al QR) copiar la clave manual que aparece debajo del QR y pegarla en la app
- La app empieza a generar códigos de 6 dígitos que cambian cada 30 segundos
- Ingresar el código actual en la pantalla de Eval360Pro
- Click Activar 2FA
A partir de ese momento, cada login pide: - Email + contraseña (paso 1) - Código de 6 dígitos del autenticador (paso 2)
Desactivación¶
Mi perfil → tab Autenticación de dos factores → botón Desactivar 2FA.
No requiere ingresar código (asume que ya estás logueado, lo cual implica que pasaste el 2FA recientemente). Audit log: auth.2fa.disabled.
Login con 2FA¶
- Ingresar email + password en
/Account/Login - Si la cuenta tiene 2FA activo, redirige a
/Account/LoginWith2fa - Ingresar código de 6 dígitos
- Si correcto → entra a la app
Códigos de respaldo (recovery codes)¶
No están implementados en la versión actual. Si pierdes el dispositivo con el autenticador, la única recuperación es:
- Pedirle a un administrador de tu tenant que te resetee 2FA via la sección de Usuarios
Recomendaciones¶
- Obligatorio para administradores (TenantAdmin, SystemAdmin) — son los blancos de mayor valor
- Opcional para empleados — se puede recomendar pero forzarlo a todos suele generar fricción
Gestión de usuarios y sesiones¶
Acceso¶
Usuarios y sesiones (menú lateral) — rol TenantAdmin o SystemAdmin.
Lista de usuarios del tenant¶
Filtros disponibles: - Búsqueda por nombre o email - "Solo bloqueados" — usuarios con cuenta bloqueada por intentos fallidos
Columnas: - Nombre - Email - Activo (sí/no) - Bloqueado (sí/no — por intentos fallidos) - Intentos fallidos (contador) - Último login - 2FA habilitado
Acciones por usuario¶
| Acción | Efecto |
|---|---|
| Editar | Cambiar nombre, email, idioma preferido, roles asignados |
| Resetear contraseña | Genera contraseña temporal nueva (12 chars con mayúscula/minúscula/dígito/símbolo). El admin la ve una sola vez para comunicarla al usuario |
| Activar / Desactivar | Si desactivado, el usuario no puede loguearse. Sus sesiones activas se revocan inmediatamente |
| Desbloquear | Si quedó bloqueado por intentos fallidos (ver Lockout abajo). Resetea el contador |
| Sesiones | Ver tokens JWT activos del usuario y revocar todas |
Roles asignables¶
Al editar un usuario, puedes asignarle uno o varios roles:
- TenantAdmin
- HRManager
- Manager
- Employee
SystemAdmin no se asigna desde la UI del tenant: lo gestiona el SystemAdmin a nivel plataforma vía SQL o seeder.
Lockout (bloqueo por intentos fallidos)¶
Configuración por default:
| Parámetro | Valor |
|---|---|
| Max intentos fallidos | 5 |
| Duración del bloqueo | 10 minutos |
Después de 5 intentos fallidos consecutivos, la cuenta queda bloqueada 10 minutos. El usuario verá mensaje "Cuenta bloqueada, reintentar más tarde" al intentar loguear.
Un admin puede desbloquear manualmente desde Usuarios y sesiones → Desbloquear.
Los intentos exitosos resetean el contador.
Audit log: cada intento fallido genera auth.login.failure con reason: LOCKED_OUT.
Sesiones activas¶
Cookie session (Razor MVC)¶
- Cookie httpOnly + Secure (en HTTPS) + SameSite=Lax
- Expiración: 8 horas desde el último request
- Sliding expiration habilitada (cada request renueva)
- Cuando un usuario se desactiva o sus roles cambian, la cookie sigue valida hasta que expira o el usuario hace logout (ASP.NET Core Identity solo revalida claims periódicamente). Para forzar logout inmediato, usar Revocar todas las sesiones
JWT Bearer (API)¶
- Access token: ~1 hora de validez (configurable en
Jwt.AccessTokenLifetimeMinutes) - Refresh token: persistido en tabla
RefreshTokens, ~30 días por default (configurable) - Logout (POST
/api/auth/logout) invalida el refresh token (soft-revoke)
Revocar todas las sesiones de un usuario¶
Usuarios → buscar usuario → click en Sesiones → Revocar todas.
Efecto: - Tokens JWT del usuario quedan inválidos en el próximo request - La cookie de sesión también se invalida (security stamp) - Usuario tiene que re-loguear
Útil cuando se sospecha credenciales comprometidas.
Rate limiting¶
Para mitigar ataques de fuerza bruta:
- Endpoints de auth (
/Account/Login,/Account/ForgotPassword,/Account/LoginWith2fa,/api/auth/token) tienen rate limiting con políticaauth - Si se supera el límite, devuelve HTTP 429 con
errorCode: RATE_LIMITED
Configuración por default (Program.cs):
- 10 requests por minuto por IP
- Aplicable solo a las rutas de autenticación
El resto de la app usa el limit global más permisivo (200 req/min por IP).
Recomendaciones de seguridad¶
- Activar 2FA en TODAS las cuentas con rol
TenantAdminoSystemAdmin - Cambiar la contraseña inicial del primer SystemAdmin (
sysadmin@eval360pro.local) inmediatamente después del primer arranque - Después del primer arranque, poner
Seed:Enabled = falseenappsettings.Production.jsonpara evitar regenerar el SystemAdmin si alguien borra la cuenta - Revisar audit log periódicamente buscando patrones sospechosos (
auth.login.failurerepetidos desde la misma IP) - En entornos sensibles, considerar restringir IPs a nivel firewall o con reverse proxy en frente