diff --git a/OIDC_IMPLEMENTATION_PLAN.md b/OIDC_IMPLEMENTATION_PLAN.md deleted file mode 100644 index d8bf612e2..000000000 --- a/OIDC_IMPLEMENTATION_PLAN.md +++ /dev/null @@ -1,814 +0,0 @@ -# Plan de Implementación: Autenticación OIDC en Ghostfolio - -**Fecha de inicio**: 3 de noviembre de 2025 -**Estado**: 🟡 En planificación - ---- - -## 📋 Análisis de Autenticación Actual - -### 🔐 Métodos de Autenticación Existentes - -#### 1. **Autenticación Anónima (Access Token)** - -- ✅ **Ubicación**: `apps/api/src/app/auth/auth.controller.ts` y `auth.service.ts` -- **Funcionamiento**: - - Los usuarios crean una cuenta y reciben un `accessToken` - - El token se hashea con salt y se valida contra la base de datos - - Genera un JWT tras validación exitosa -- **Endpoints**: - - `POST /api/auth/anonymous` (actual) - - `GET /api/auth/anonymous/:accessToken` (deprecated) - -#### 2. **OAuth 2.0 con Google** - -- ✅ **Ubicación**: `apps/api/src/app/auth/google.strategy.ts` -- **Implementación**: - - Usa `passport-google-oauth20` - - Flujo estándar OAuth 2.0 - - Callback URL: `/api/auth/google/callback` - - Scope: `['profile']` (solo perfil básico) -- **Variables de entorno**: - - `GOOGLE_CLIENT_ID` - - `GOOGLE_SECRET` - - `ROOT_URL` - -#### 3. **WebAuthn (Autenticación sin contraseña)** - -- ✅ **Ubicación**: `apps/api/src/app/auth/web-auth.service.ts` -- **Implementación**: - - Usa `@simplewebauthn/server` y `@simplewebauthn/browser` - - Soporte para dispositivos biométricos (Face ID, Touch ID, etc.) - - Registro y autenticación de dispositivos -- **Endpoints**: - - `GET /api/auth/webauthn/generate-registration-options` - - `POST /api/auth/webauthn/verify-attestation` - - `POST /api/auth/webauthn/generate-authentication-options` - - `POST /api/auth/webauthn/verify-authentication` - -#### 4. **API Key Authentication** - -- ✅ **Ubicación**: `apps/api/src/app/auth/api-key.strategy.ts` -- **Funcionamiento**: - - Usa `passport-headerapikey` - - Header: `x-api-key` con prefijo `Api-Key` - - Para integración con APIs externas - -#### 5. **JWT Bearer Token** - -- ✅ **Ubicación**: `apps/api/src/app/auth/jwt.strategy.ts` -- **Implementación**: - - Estrategia principal de autorización - - Expira en 180 días - - Extracción desde Authorization header - - Validación de usuarios inactivos y analytics - -### 📊 Modelo de Datos Actual (Prisma) - -```prisma -enum Provider { - ANONYMOUS - GOOGLE - INTERNET_IDENTITY // No implementado actualmente -} - -model User { - // ... otros campos - provider Provider @default(ANONYMOUS) - thirdPartyId String? - // ... -} -``` - ---- - -## 🎯 Plan de Implementación OIDC - -### **Fase 1: Análisis y Diseño** ✅ - -- [x] Analizar métodos de autenticación existentes -- [x] Diseñar arquitectura de integración OIDC -- [x] Definir enfoque de coexistencia con métodos actuales -- [x] Decidir estrategia de provider genérico vs específico - -**Decisiones de diseño**: - -1. Estrategia genérica OIDC configurable para múltiples proveedores -2. OIDC coexistirá con los métodos existentes -3. Añadir nuevo valor `OIDC` al enum Provider -4. Usar campo `thirdPartyId` existente para almacenar `sub` del token OIDC - ---- - -### **Fase 2: Cambios en la Base de Datos** ⏳ - -- [ ] Modificar `prisma/schema.prisma` para añadir Provider.OIDC -- [ ] (Opcional) Añadir campo `oidcIssuer` para distinguir proveedores -- [ ] Crear migración de base de datos -- [ ] Ejecutar migración en desarrollo -- [ ] Validar cambios en base de datos - -#### Cambios necesarios en `prisma/schema.prisma` - -```prisma -enum Provider { - ANONYMOUS - GOOGLE - INTERNET_IDENTITY - OIDC // 🆕 Añadir -} - -// Opcional: Si se necesita distinguir múltiples proveedores OIDC -model User { - // ... campos existentes - oidcIssuer String? // 🆕 Para identificar el proveedor OIDC específico -} -``` - -#### Comandos a ejecutar - -```bash -# Crear migración -npx prisma migrate dev --name add_oidc_provider - -# O push directo para desarrollo -npm run database:push -``` - -**Archivos afectados**: - -- `prisma/schema.prisma` -- `prisma/migrations/YYYYMMDD_add_oidc_provider/migration.sql` (nuevo) - ---- - -### **Fase 3: Dependencias** ⏳ - -- [ ] Instalar `passport-openidconnect` -- [ ] Instalar `@types/passport-openidconnect` -- [ ] Verificar compatibilidad de versiones -- [ ] Actualizar `package.json` y `package-lock.json` - -#### Comandos a ejecutar - -```bash -npm install passport-openidconnect -npm install --save-dev @types/passport-openidconnect -``` - -**Archivos afectados**: - -- `package.json` -- `package-lock.json` - ---- - -### **Fase 4: Variables de Entorno** ⏳ - -- [ ] Actualizar `.env.example` con variables OIDC -- [ ] Documentar cada variable de entorno -- [ ] Crear configuración de ejemplo para proveedores comunes -- [ ] Añadir variables al ConfigurationService si es necesario - -#### Añadir a `.env.example` - -```bash -# ==================================== -# OIDC Authentication Configuration -# ==================================== -# Enable/disable OIDC authentication -OIDC_ENABLED=false - -# OIDC Provider base URL (must be HTTPS in production) -OIDC_ISSUER=https://your-oidc-provider.com - -# OAuth 2.0 Client credentials -OIDC_CLIENT_ID= -OIDC_CLIENT_SECRET= - -# Callback URL (where OIDC provider redirects after authentication) -OIDC_CALLBACK_URL=${ROOT_URL}/api/auth/oidc/callback - -# OpenID Connect scopes (space-separated) -OIDC_SCOPE=openid profile email - -# Optional: Override default endpoints (auto-discovered from issuer if not set) -# OIDC_AUTHORIZATION_URL=https://your-oidc-provider.com/authorize -# OIDC_TOKEN_URL=https://your-oidc-provider.com/token -# OIDC_USER_INFO_URL=https://your-oidc-provider.com/userinfo -``` - -#### Ejemplos de configuración por proveedor - -
-Keycloak - -```bash -OIDC_ENABLED=true -OIDC_ISSUER=https://keycloak.example.com/realms/your-realm -OIDC_CLIENT_ID=ghostfolio -OIDC_CLIENT_SECRET=your-secret-here -OIDC_SCOPE=openid profile email -``` - -
- -
-Auth0 - -```bash -OIDC_ENABLED=true -OIDC_ISSUER=https://your-tenant.auth0.com -OIDC_CLIENT_ID=your-client-id -OIDC_CLIENT_SECRET=your-secret-here -OIDC_SCOPE=openid profile email -``` - -
- -
-Azure AD - -```bash -OIDC_ENABLED=true -OIDC_ISSUER=https://login.microsoftonline.com/{tenant-id}/v2.0 -OIDC_CLIENT_ID=your-application-id -OIDC_CLIENT_SECRET=your-client-secret -OIDC_SCOPE=openid profile email -``` - -
- -
-Okta - -```bash -OIDC_ENABLED=true -OIDC_ISSUER=https://your-domain.okta.com -OIDC_CLIENT_ID=your-client-id -OIDC_CLIENT_SECRET=your-client-secret -OIDC_SCOPE=openid profile email -``` - -
- -**Archivos afectados**: - -- `.env.example` -- (Posiblemente) `apps/api/src/services/configuration/configuration.service.ts` - ---- - -### **Fase 5: Implementación Backend** ⏳ - -#### 5.1. Crear estrategia OIDC ⏳ - -- [ ] Crear archivo `apps/api/src/app/auth/oidc.strategy.ts` -- [ ] Implementar clase OidcStrategy extendiendo PassportStrategy -- [ ] Configurar discovery automático de endpoints -- [ ] Implementar método validate -- [ ] Manejar errores y logging -- [ ] Añadir validación de configuración - -**Archivo a crear**: `apps/api/src/app/auth/oidc.strategy.ts` - -```typescript -import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; -import { Injectable, Logger } from '@nestjs/common'; -import { PassportStrategy } from '@nestjs/passport'; -import { Provider } from '@prisma/client'; -import { Strategy, VerifyCallback } from 'passport-openidconnect'; -import { AuthService } from './auth.service'; - -@Injectable() -export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { - private static readonly logger = new Logger(OidcStrategy.name); - - public constructor( - private readonly authService: AuthService, - configurationService: ConfigurationService - ) { - const issuer = configurationService.get('OIDC_ISSUER'); - const clientID = configurationService.get('OIDC_CLIENT_ID'); - const clientSecret = configurationService.get('OIDC_CLIENT_SECRET'); - const enabled = configurationService.get('OIDC_ENABLED') === 'true'; - - if (!enabled || !issuer || !clientID || !clientSecret) { - OidcStrategy.logger.warn( - 'OIDC authentication is not configured or disabled. ' + - 'Set OIDC_ENABLED=true and provide OIDC_ISSUER, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET.' - ); - // Passport requiere configuración válida, usar placeholders - super({ - issuer: 'https://placeholder.example.com', - clientID: 'placeholder', - clientSecret: 'placeholder', - authorizationURL: 'https://placeholder.example.com/authorize', - tokenURL: 'https://placeholder.example.com/token', - userInfoURL: 'https://placeholder.example.com/userinfo', - callbackURL: 'https://placeholder.example.com/callback', - scope: 'openid profile' - }); - return; - } - - const callbackURL = configurationService.get('OIDC_CALLBACK_URL') || - `${configurationService.get('ROOT_URL')}/api/auth/oidc/callback`; - - const scope = configurationService.get('OIDC_SCOPE') || 'openid profile email'; - - // Los endpoints se descubren automáticamente desde el issuer si no se proporcionan - const config: any = { - issuer, - clientID, - clientSecret, - callbackURL, - scope: scope.split(' '), - passReqToCallback: true - }; - - // Endpoints opcionales (si no se proporcionan, se descubren automáticamente) - const authorizationURL = configurationService.get('OIDC_AUTHORIZATION_URL'); - const tokenURL = configurationService.get('OIDC_TOKEN_URL'); - const userInfoURL = configurationService.get('OIDC_USER_INFO_URL'); - - if (authorizationURL) config.authorizationURL = authorizationURL; - if (tokenURL) config.tokenURL = tokenURL; - if (userInfoURL) config.userInfoURL = userInfoURL; - - super(config); - - OidcStrategy.logger.log( - `OIDC authentication configured with issuer: ${issuer}` - ); - } - - public async validate( - _request: any, - _issuer: string, - profile: any, - _context: any, - _idToken: any, - _accessToken: any, - _refreshToken: any, - params: any, - done: VerifyCallback - ) { - try { - // El 'sub' (subject) del token es el identificador único del usuario - const thirdPartyId = params.sub || profile.id; - - if (!thirdPartyId) { - throw new Error('No subject (sub) found in OIDC token'); - } - - OidcStrategy.logger.debug( - `Validating OIDC user with sub: ${thirdPartyId}` - ); - - const jwt = await this.authService.validateOAuthLogin({ - provider: Provider.OIDC, - thirdPartyId - }); - - done(null, { jwt, profile }); - } catch (error) { - OidcStrategy.logger.error( - `OIDC validation error: ${error.message}`, - error.stack - ); - done(error, false); - } - } -} -``` - -#### 5.2. Actualizar módulo de autenticación ⏳ - -- [ ] Importar OidcStrategy en `auth.module.ts` -- [ ] Añadir OidcStrategy a providers -- [ ] Verificar importaciones - -**Archivo a modificar**: `apps/api/src/app/auth/auth.module.ts` - -Añadir: - -```typescript -import { OidcStrategy } from './oidc.strategy'; - -@Module({ - // ... - providers: [ - ApiKeyService, - ApiKeyStrategy, - AuthDeviceService, - AuthService, - GoogleStrategy, - JwtStrategy, - OidcStrategy, // 🆕 Añadir aquí - WebAuthService - ] -}) -export class AuthModule {} -``` - -#### 5.3. Añadir endpoints al controlador ⏳ - -- [ ] Añadir endpoint `/auth/oidc` para iniciar login -- [ ] Añadir endpoint `/auth/oidc/callback` para callback -- [ ] Implementar manejo de errores -- [ ] Añadir guard condicional si OIDC está deshabilitado - -**Archivo a modificar**: `apps/api/src/app/auth/auth.controller.ts` - -Añadir antes del último endpoint: - -```typescript -@Get('oidc') -@UseGuards(AuthGuard('oidc')) -public oidcLogin() { - // Inicia el flujo de autenticación OIDC - // Passport redirige automáticamente al proveedor OIDC -} - -@Get('oidc/callback') -@UseGuards(AuthGuard('oidc')) -@Version(VERSION_NEUTRAL) -public oidcLoginCallback( - @Req() request: Request, - @Res() response: Response -) { - // Maneja el callback del proveedor OIDC - const jwt: string = (request.user as any).jwt; - - if (jwt) { - response.redirect( - `${this.configurationService.get('ROOT_URL')}/${DEFAULT_LANGUAGE_CODE}/auth/${jwt}` - ); - } else { - // Error en autenticación - response.redirect( - `${this.configurationService.get('ROOT_URL')}/${DEFAULT_LANGUAGE_CODE}/auth?error=oidc_failed` - ); - } -} -``` - -#### 5.4. Verificar AuthService ⏳ - -- [ ] Confirmar que `validateOAuthLogin` funciona con Provider.OIDC -- [ ] Añadir lógica específica si es necesario (ej: almacenar issuer) -- [ ] Verificar creación de usuarios nuevos -- [ ] Verificar que property `isUserSignupEnabled` se respeta - -**Archivo a revisar**: `apps/api/src/app/auth/auth.service.ts` - -El método existente ya debería funcionar: - -```typescript -public async validateOAuthLogin({ - provider, - thirdPartyId -}: ValidateOAuthLoginParams): Promise { - // Este método ya soporta cualquier provider del enum - // No requiere cambios si Provider.OIDC está en el enum -} -``` - -#### 5.5. Testing backend ⏳ - -- [ ] Crear tests unitarios para OidcStrategy -- [ ] Crear tests de integración para endpoints -- [ ] Verificar manejo de errores -- [ ] Test con configuración inválida/faltante - -**Archivos a crear**: - -- `apps/api/src/app/auth/oidc.strategy.spec.ts` - ---- - -### **Fase 6: Implementación Frontend** ⏳ - -#### 6.1. Añadir botón de login OIDC ⏳ - -- [ ] Identificar componente de login actual -- [ ] Añadir botón "Sign in with OIDC" o customizable -- [ ] Implementar redirección a `/api/auth/oidc` -- [ ] Añadir iconografía apropiada -- [ ] Hacer el botón condicional (mostrar solo si OIDC está habilitado) - -**Archivos a investigar**: - -- `apps/client/src/app/pages/landing/` -- `apps/client/src/app/pages/webauthn/` -- Componentes relacionados con login/auth - -#### 6.2. Verificar flujo de redirección ⏳ - -- [ ] Confirmar que `/auth/:jwt` maneja correctamente el token OIDC -- [ ] Añadir manejo de errores (parámetro `?error=oidc_failed`) -- [ ] Verificar storage del token -- [ ] Probar navegación post-login - -**Archivo a revisar**: `apps/client/src/app/pages/auth/auth-page.component.ts` - -#### 6.3. Configuración visual (opcional) ⏳ - -- [ ] Permitir customización del texto del botón via config -- [ ] Permitir customización del logo del proveedor -- [ ] Responsive design para botón OIDC - -#### 6.4. Testing frontend ⏳ - -- [ ] Test unitario del componente con botón OIDC -- [ ] Test e2e del flujo completo -- [ ] Verificar en diferentes navegadores - ---- - -### **Fase 7: Configuración y Seguridad** ⏳ - -#### 7.1. Validaciones de seguridad ⏳ - -- [ ] Validar que OIDC_ISSUER sea HTTPS en producción -- [ ] Implementar validación de state/nonce -- [ ] Verificar validación de firma de tokens JWT -- [ ] Implementar timeout de sesión configurable -- [ ] Añadir rate limiting a endpoints OIDC - -#### 7.2. ConfigurationService ⏳ - -- [ ] Verificar que todas las variables OIDC están disponibles -- [ ] Añadir validación de variables requeridas al inicio -- [ ] Implementar feature flag para OIDC_ENABLED - -**Archivo a modificar (posiblemente)**: - -- `apps/api/src/services/configuration/configuration.service.ts` - -#### 7.3. Logging y monitoreo ⏳ - -- [ ] Añadir logs de eventos OIDC importantes -- [ ] Implementar métricas de autenticación OIDC -- [ ] Añadir alertas para fallos de autenticación - -#### 7.4. Multi-issuer (Opcional avanzado) ⏳ - -Si se necesita soportar múltiples proveedores OIDC simultáneamente: - -- [ ] Añadir campo `oidcIssuer` al modelo User -- [ ] Modificar `validateOAuthLogin` para incluir issuer -- [ ] Crear estrategias dinámicas por issuer -- [ ] Añadir UI para seleccionar proveedor - ---- - -### **Fase 8: Testing Integral** ⏳ - -#### 8.1. Testing local ⏳ - -- [ ] Configurar Keycloak local en Docker -- [ ] Probar flujo completo de registro nuevo usuario -- [ ] Probar flujo completo de login usuario existente -- [ ] Probar manejo de errores (credenciales inválidas) -- [ ] Probar con OIDC deshabilitado - -#### 8.2. Testing con proveedores reales ⏳ - -- [ ] Keycloak -- [ ] Auth0 -- [ ] Azure AD -- [ ] Okta -- [ ] Otro proveedor OIDC genérico - -#### 8.3. Testing de regresión ⏳ - -- [ ] Verificar que Google OAuth sigue funcionando -- [ ] Verificar que autenticación anónima sigue funcionando -- [ ] Verificar que WebAuthn sigue funcionando -- [ ] Verificar que API Keys siguen funcionando - -#### 8.4. Testing de seguridad ⏳ - -- [ ] Intentar bypass de autenticación -- [ ] Verificar protección CSRF -- [ ] Verificar manejo de tokens expirados -- [ ] Penetration testing básico - ---- - -### **Fase 9: Documentación** ⏳ - -#### 9.1. Documentación técnica ⏳ - -- [ ] Actualizar `DEVELOPMENT.md` con setup OIDC -- [ ] Documentar arquitectura de autenticación -- [ ] Crear diagrama de flujo OIDC -- [ ] Documentar variables de entorno - -**Archivo a modificar**: `DEVELOPMENT.md` - -Sección a añadir: - -````markdown -### OIDC Authentication Setup - -Ghostfolio supports OpenID Connect (OIDC) authentication with any compliant provider. - -#### Configuration - -1. Set up your OIDC provider (Keycloak, Auth0, Azure AD, Okta, etc.) -2. Register Ghostfolio as a client application -3. Configure the following environment variables in your `.env` file: - -```bash -OIDC_ENABLED=true -OIDC_ISSUER=https://your-provider.com -OIDC_CLIENT_ID=your-client-id -OIDC_CLIENT_SECRET=your-client-secret -OIDC_CALLBACK_URL=https://your-ghostfolio-instance.com/api/auth/oidc/callback -OIDC_SCOPE=openid profile email -``` -```` - -4. Restart the Ghostfolio server -5. Users can now authenticate using the "Sign in with OIDC" button - -#### Provider-Specific Setup Guides - -See [docs/oidc-providers.md](docs/oidc-providers.md) for detailed setup instructions for: - -- Keycloak -- Auth0 -- Azure Active Directory -- Okta -- Generic OIDC providers - -``` - -#### 9.2. Guías de configuración por proveedor ⏳ - -- [ ] Crear `docs/oidc-providers.md` con guías detalladas -- [ ] Incluir screenshots del proceso de configuración -- [ ] Documentar troubleshooting común por proveedor - -**Archivo a crear**: `docs/oidc-providers.md` - -#### 9.3. Documentación de usuario ⏳ - -- [ ] Actualizar FAQ sobre métodos de autenticación -- [ ] Crear guía de usuario para login con OIDC -- [ ] Documentar cómo migrar de un método a otro - -#### 9.4. Changelog ⏳ - -- [ ] Actualizar `CHANGELOG.md` con nueva feature OIDC -- [ ] Documentar breaking changes si los hay -- [ ] Listar proveedores OIDC probados - -**Archivo a modificar**: `CHANGELOG.md` - ---- - -### **Fase 10: Deployment y Rollout** ⏳ - -#### 10.1. Preparación para producción ⏳ - -- [ ] Crear checklist de deployment -- [ ] Documentar proceso de rollback -- [ ] Preparar scripts de migración de BD -- [ ] Configurar variables de entorno en producción - -#### 10.2. Deployment gradual ⏳ - -- [ ] Desplegar en entorno de staging -- [ ] Testing en staging con usuarios beta -- [ ] Desplegar en producción con feature flag deshabilitado -- [ ] Habilitar OIDC gradualmente - -#### 10.3. Monitoreo post-deployment ⏳ - -- [ ] Monitorear logs de errores OIDC -- [ ] Monitorear tasa de éxito de autenticación -- [ ] Recopilar feedback de usuarios -- [ ] Ajustar configuración según necesidad - ---- - -## 📊 Progreso General - -``` - -[██████░░░░░░░░░░░░░░] 30% - Fase 1 completada - -Fase 1: Análisis y Diseño ✅ 100% -Fase 2: Base de Datos ⏳ 0% -Fase 3: Dependencias ⏳ 0% -Fase 4: Variables de Entorno ⏳ 0% -Fase 5: Backend ⏳ 0% -Fase 6: Frontend ⏳ 0% -Fase 7: Seguridad ⏳ 0% -Fase 8: Testing ⏳ 0% -Fase 9: Documentación ⏳ 0% -Fase 10: Deployment ⏳ 0% - -``` - ---- - -## 📝 Archivos a Crear - -### Nuevos archivos backend: -- [ ] `apps/api/src/app/auth/oidc.strategy.ts` -- [ ] `apps/api/src/app/auth/oidc.strategy.spec.ts` - -### Nuevos archivos de documentación: -- [ ] `docs/oidc-providers.md` -- [x] `OIDC_IMPLEMENTATION_PLAN.md` (este archivo) - ---- - -## 📝 Archivos a Modificar - -### Backend: -- [ ] `prisma/schema.prisma` (añadir Provider.OIDC y opcionalmente oidcIssuer) -- [ ] `apps/api/src/app/auth/auth.module.ts` (registrar OidcStrategy) -- [ ] `apps/api/src/app/auth/auth.controller.ts` (añadir endpoints OIDC) -- [ ] `apps/api/src/app/auth/auth.service.ts` (verificar, posibles ajustes) -- [ ] `apps/api/src/services/configuration/configuration.service.ts` (posible) - -### Configuración: -- [ ] `.env.example` (añadir variables OIDC) -- [ ] `package.json` (nuevas dependencias) - -### Frontend: -- [ ] Componente de login (añadir botón OIDC) -- [ ] `apps/client/src/app/pages/auth/auth-page.component.ts` (manejo de errores) - -### Documentación: -- [ ] `DEVELOPMENT.md` (instrucciones de configuración OIDC) -- [ ] `CHANGELOG.md` (documentar nueva feature) -- [ ] `README.md` (mencionar soporte OIDC) - ---- - -## 🎯 Próximos Pasos Inmediatos - -1. **Comenzar Fase 2**: Modificar schema de Prisma -2. **Instalar dependencias**: passport-openidconnect -3. **Crear estrategia OIDC**: Implementar oidc.strategy.ts - ---- - -## 🔧 Consideraciones Técnicas - -### Ventajas de este enfoque: -✅ Mínima invasión en código existente -✅ Aprovecha arquitectura Passport ya establecida -✅ Flexible para cualquier proveedor OIDC -✅ Coexiste con métodos de autenticación actuales -✅ Fácil de mantener y extender -✅ Bien documentado y testeable - -### Posibles desafíos: -⚠️ Configuración puede ser compleja para usuarios finales -⚠️ Diferentes proveedores OIDC tienen quirks específicos -⚠️ Testing requiere configuración de provider de desarrollo -⚠️ Manejo de múltiples issuers añade complejidad - -### Alternativas consideradas: -- **OAuth2 específico por proveedor**: Más trabajo, menos flexible -- **Auth0/Keycloak como único proveedor**: Limita opciones de usuarios -- **Passport-oauth2 genérico**: OIDC es más estándar y específico - ---- - -## 📚 Referencias - -### Documentación relevante: -- [OpenID Connect Specification](https://openid.net/connect/) -- [Passport-OpenIDConnect Strategy](https://github.com/jaredhanson/passport-openidconnect) -- [NestJS Passport Integration](https://docs.nestjs.com/security/authentication) -- [Prisma Schema Reference](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference) - -### Proveedores OIDC para testing: -- [Keycloak (self-hosted)](https://www.keycloak.org/) -- [Auth0](https://auth0.com/) -- [Azure AD](https://azure.microsoft.com/en-us/services/active-directory/) -- [Okta](https://www.okta.com/) - ---- - -## 📞 Contacto y Soporte - -Para preguntas o problemas durante la implementación: -- Revisar logs en `apps/api/src/app/auth/oidc.strategy.ts` -- Verificar configuración de variables de entorno -- Consultar documentación del proveedor OIDC específico - ---- - -**Última actualización**: 3 de noviembre de 2025 -**Versión del plan**: 1.0 -``` diff --git a/apps/api/src/app/auth/oidc.strategy.ts b/apps/api/src/app/auth/oidc.strategy.ts index 835fcb820..cc9a8ecc4 100644 --- a/apps/api/src/app/auth/oidc.strategy.ts +++ b/apps/api/src/app/auth/oidc.strategy.ts @@ -91,9 +91,6 @@ export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { _refreshToken: any, params: any ) { - // El 'sub' (subject) del ID Token es el identificador único estándar de OIDC - // Según OpenID Connect Core 1.0, el 'sub' es el identificador único e inmutable del usuario - // El 'sub' viene en el idToken parseado o en params const thirdPartyId = params?.sub || idToken?.sub || context?.claims?.sub || profile?.id;