# Investigation Erreur 502 - Redirection depuis Keycloak ## 🔍 Problème Identifié **Symptôme** : Erreur 502 après redirection depuis Keycloak après authentification **Logs observés** : ``` Keycloak profile callback: { rawProfile: { ... }, rawRoles: undefined, realmAccess: undefined, // ⚠️ PROBLÈME ICI groups: [ ... ] // ✅ Groups présents } Profile callback raw roles: [] Profile callback cleaned roles: [] ``` ## 🎯 Cause Racine Le profil Keycloak (ID token) **ne contient pas** `realm_access.roles`, mais contient `groups`. Les rôles sont probablement dans le **token d'accès**, pas dans le token ID. ## ✅ Correction Appliquée **Fichier** : `app/api/auth/options.ts` - Callback JWT **Changements** : 1. ✅ Extraction des rôles depuis le **token d'accès** (pas seulement le profil) 2. ✅ Fallback sur `groups` si pas de rôles 3. ✅ Logs améliorés pour debugging **Code modifié** : ```typescript // Avant : Seulement depuis profile const roles = keycloakProfile.realm_access?.roles || []; // Après : Multi-sources 1. Essayer depuis profile (ID token) 2. Si vide, décoder access token 3. Si toujours vide, utiliser groups comme fallback ``` ## 🔍 Points d'Investigation pour l'Erreur 502 ### 1. Vérifier les logs serveur Next.js complets **Où chercher** : - Terminal Next.js (erreurs complètes) - Logs de production (si déployé) - Console navigateur (erreurs client) **Commandes utiles** : ```bash # Voir tous les logs npm run dev 2>&1 | tee logs.txt # Filtrer les erreurs npm run dev 2>&1 | grep -i "error\|502\|exception" ``` ### 2. Vérifier le callback NextAuth **Fichier** : `app/api/auth/callback/keycloak` (géré par NextAuth) **Points à vérifier** : - ✅ Le callback reçoit bien le code OAuth - ✅ L'échange code → tokens fonctionne - ✅ Le callback JWT s'exécute sans erreur - ✅ Le callback session s'exécute sans erreur **Ajouter des logs** : ```typescript // Dans options.ts, callback jwt console.log('JWT callback - account:', !!account, 'profile:', !!profile); console.log('JWT callback - accessToken length:', account?.access_token?.length); console.log('JWT callback - roles extracted:', cleanRoles); ``` ### 3. Vérifier l'initialisation storage **Fichier** : `app/api/storage/init/route.ts` **Problème potentiel** : - Si `createUserFolderStructure()` échoue, ça peut causer une 502 - Si la session n'est pas encore complètement créée **Vérifications** : ```typescript // Vérifier si l'erreur vient de là console.log('Storage init - session:', session); console.log('Storage init - user id:', session?.user?.id); ``` ### 4. Vérifier la configuration Keycloak **Problème potentiel** : - Les rôles ne sont pas mappés correctement dans Keycloak - Le scope "roles" n'est pas configuré correctement - Les mappers de token ne sont pas configurés **À vérifier dans Keycloak** : 1. **Client Configuration** : - Scope "roles" est-il activé ? - Mapper "realm roles" est-il configuré ? 2. **Token Mappers** : - `realm_access.roles` mapper existe-t-il ? - Est-il ajouté au token d'accès ? 3. **User Roles** : - L'utilisateur a-t-il des rôles assignés dans le realm ? ### 5. Vérifier les erreurs dans le callback session **Fichier** : `app/api/auth/options.ts` - Callback session **Problème potentiel** : - Si `token.role` est undefined et qu'un code s'attend à un array - Si `session.user` est mal formé **Vérifications** : ```typescript // Dans callback session console.log('Session callback - token.role:', token.role); console.log('Session callback - token.error:', token.error); console.log('Session callback - hasAccessToken:', !!token.accessToken); ``` ### 6. Vérifier les timeouts **Problème potentiel** : - Timeout lors de l'appel à Keycloak pour échanger le code - Timeout lors de l'initialisation storage - Timeout lors de la création de la session **Solutions** : - Augmenter les timeouts si nécessaire - Vérifier la latence réseau vers Keycloak ## 🛠️ Actions Immédiates ### Action 1 : Ajouter plus de logs **Fichier** : `app/api/auth/options.ts` ```typescript // Dans callback jwt, après extraction des rôles console.log('=== JWT CALLBACK DEBUG ==='); console.log('Has account:', !!account); console.log('Has profile:', !!profile); console.log('Access token present:', !!account?.access_token); console.log('Roles from profile:', keycloakProfile.realm_access?.roles); console.log('Roles from access token:', roles); console.log('Final roles:', cleanRoles); console.log('=========================='); ``` ### Action 2 : Vérifier l'erreur exacte **Dans le terminal Next.js**, chercher : - Stack trace complète - Message d'erreur exact - Ligne de code qui cause l'erreur ### Action 3 : Tester avec un utilisateur simple **Tester avec** : - Un utilisateur avec des rôles - Un utilisateur sans rôles - Vérifier si l'erreur est liée aux rôles ### Action 4 : Vérifier la configuration Keycloak **Dans Keycloak Admin Console** : 1. **Client → Mappers** : - Vérifier qu'il y a un mapper "realm roles" - Vérifier qu'il est ajouté au token d'accès - Vérifier qu'il ajoute `realm_access.roles` 2. **Client → Settings** : - Vérifier que "Full Scope Allowed" est activé - Vérifier les "Default Client Scopes" incluent "roles" 3. **Realm → Roles** : - Vérifier que l'utilisateur a des rôles assignés ## 📊 Checklist de Debugging - [ ] Logs serveur Next.js complets vérifiés - [ ] Erreur exacte identifiée (stack trace) - [ ] Callback JWT s'exécute sans erreur - [ ] Callback session s'exécute sans erreur - [ ] Rôles extraits correctement (depuis access token) - [ ] Storage init fonctionne - [ ] Configuration Keycloak vérifiée - [ ] Mappers Keycloak vérifiés - [ ] Timeouts vérifiés ## 🔧 Solution Temporaire (si nécessaire) Si l'erreur persiste, on peut temporairement utiliser les `groups` comme rôles : ```typescript // Dans profile callback const roles = keycloakProfile.realm_access?.roles || keycloakProfile.groups || []; ``` **Note** : Ce n'est qu'une solution temporaire. Il faut corriger la configuration Keycloak pour avoir les rôles correctement mappés. ## 📝 Prochaines Étapes 1. ✅ **Correction appliquée** : Extraction rôles depuis access token 2. ⏳ **À faire** : Vérifier les logs serveur pour l'erreur exacte 3. ⏳ **À faire** : Vérifier configuration Keycloak 4. ⏳ **À faire** : Tester après correction --- **Document créé le** : $(date) **Statut** : Correction appliquée, investigation en cours