# Resolution des erreurs OIDC - Guide complet ## Erreurs rencontrees et solutions appliquees ### ❌ ERREUR 1: "Secret key for encrypting state cookie is less than 16 characters long" **Message d'erreur complet:** ``` io.quarkus.runtime.configuration.ConfigurationException: Secret key for encrypting state cookie is less than 16 characters long ``` **Cause:** Lorsque PKCE est active (`quarkus.oidc.authentication.pkce-required=true`), Quarkus a besoin d'un secret de **EXACTEMENT 32 caracteres** pour encrypter le PKCE code verifier dans le state cookie. **Solution appliquee:** Ajout de `quarkus.oidc.authentication.state-secret` avec une valeur de 32 caracteres: ```properties quarkus.oidc.authentication.state-secret=btpxpress-pkce-state-secret-32ch ``` --- ### ❌ ERREUR 2: "Both 'quarkus.oidc.authentication.state-secret' and 'quarkus.oidc.authentication.pkce-secret' are configured" **Message d'erreur complet:** ``` io.quarkus.runtime.configuration.ConfigurationException: Both 'quarkus.oidc.authentication.state-secret' and 'quarkus.oidc.authentication.pkce-secret' are configured ``` **Cause:** Quarkus OIDC ne permet PAS d'avoir les deux proprietes configurees simultanement: - `quarkus.oidc.authentication.pkce-secret=true` signifie "utilise le client secret pour PKCE" - `quarkus.oidc.authentication.state-secret=xxx` signifie "utilise CE secret dedie pour PKCE" C'est l'un OU l'autre, pas les deux! **Solution appliquee:** Mettre `pkce-secret=false` lorsqu'on utilise un `state-secret` dedie: ```properties quarkus.oidc.authentication.pkce-required=true quarkus.oidc.authentication.pkce-secret=false quarkus.oidc.authentication.state-secret=btpxpress-pkce-state-secret-32ch ``` --- ## ✅ Configuration finale valide ```properties # ========================================== # 1. Client Secret (Keycloak) # ========================================== quarkus.oidc.credentials.secret=0Ph4e31lQQuonodmLQG3JycehbFL1Hei # ========================================== # 2. PKCE Configuration # ========================================== quarkus.oidc.authentication.pkce-required=true # IMPORTANT: pkce-secret=false car on utilise state-secret quarkus.oidc.authentication.pkce-secret=false # State secret pour PKCE (EXACTEMENT 32 caracteres) quarkus.oidc.authentication.state-secret=btpxpress-pkce-state-secret-32ch # ========================================== # 3. Token Encryption (Session Cookies) # ========================================== quarkus.oidc.token-state-manager.split-tokens=true quarkus.oidc.token-state-manager.strategy=id-refresh-tokens quarkus.oidc.token-state-manager.encryption-secret=btpxpress-secure-cookie-encryption-key-32chars-2025 quarkus.oidc.token-state-manager.encryption-required=false ``` --- ## 📊 Tableau des secrets configures | Secret | Propriete | Longueur | Valeur | Usage | |--------|-----------|----------|--------|-------| | Client Secret | `quarkus.oidc.credentials.secret` | 32 chars | `0Ph4e31lQQuonodmLQG3JycehbFL1Hei` | Auth Keycloak | | State Secret | `quarkus.oidc.authentication.state-secret` | 32 chars | `btpxpress-pkce-state-secret-32ch` | PKCE verifier | | Token Encryption | `quarkus.oidc.token-state-manager.encryption-secret` | 51 chars | `btpxpress-secure-cookie-encryption-key-32chars-2025` | Session cookies | --- ## 🔄 Choix entre pkce-secret et state-secret ### Option 1: Utiliser le client secret pour PKCE (NON recommande) ```properties quarkus.oidc.authentication.pkce-required=true quarkus.oidc.authentication.pkce-secret=true # NE PAS definir state-secret ``` **Avantages:** - Moins de secrets a gerer - Configuration plus simple **Inconvenients:** - Le client secret doit faire au moins 32 caracteres - Moins de separation des responsabilites - Si le client secret change, PKCE est affecte ### Option 2: Utiliser un secret dedie pour PKCE (RECOMMANDE) ✅ ```properties quarkus.oidc.authentication.pkce-required=true quarkus.oidc.authentication.pkce-secret=false quarkus.oidc.authentication.state-secret=btpxpress-pkce-state-secret-32ch ``` **Avantages:** - Separation des responsabilites - Le client secret et le state secret peuvent etre geres independamment - Plus securise (rotation des secrets facilitee) **Inconvenients:** - Un secret supplementaire a gerer --- ## 🎯 Verification de la configuration ### Script PowerShell de verification Executer: ```powershell powershell -ExecutionPolicy Bypass -File verify-secrets.ps1 ``` **Sortie attendue:** ``` [OK] TOUS LES SECRETS SONT CORRECTEMENT CONFIGURES! ``` ### Demarrage de l'application ```bash mvn quarkus:dev ``` **Logs attendus (succes):** ``` INFO [io.quarkus.oidc] OIDC enabled DEBUG [io.quarkus.oidc] Discovered OIDC endpoints from https://security.lions.dev/realms/btpxpress/.well-known/openid-configuration ``` **Pas d'erreur "Secret key" ou "Both configured"** --- ## 🔍 Comprendre les 3 secrets ### 1. Client Secret (`credentials.secret`) - **Quand**: Echange du code d'autorisation contre des tokens - **Ou**: Requete POST vers Keycloak token endpoint - **Format**: `Authorization: Basic base64(client_id:client_secret)` ### 2. State Secret (`authentication.state-secret`) - **Quand**: Pendant la redirection vers Keycloak (etape 1 du flow) - **Ou**: Cookie `q_auth_xxx` cote client - **Contenu encrypte**: PKCE code verifier + state ### 3. Token Encryption Secret (`token-state-manager.encryption-secret`) - **Quand**: Apres reception des tokens de Keycloak - **Ou**: Cookies de session `q_session_xxx` - **Contenu encrypte**: ID token, access token, refresh token --- ## 🚀 Flux OIDC complet avec les 3 secrets ``` 1. Utilisateur accede a http://localhost:8081 └─> OIDC intercepte (page protegee) 2. Generation PKCE code verifier + code challenge └─> Encryption avec STATE SECRET └─> Stockage dans cookie q_auth 3. Redirection vers https://security.lions.dev └─> Parametres: client_id, redirect_uri, code_challenge, state 4. Utilisateur se connecte sur Keycloak └─> Keycloak valide les credentials 5. Redirection vers http://localhost:8081/dashboard.xhtml?code=XXX&state=YYY └─> Lecture cookie q_auth └─> Decryption avec STATE SECRET └─> Recuperation PKCE code verifier 6. Echange authorization code contre tokens └─> POST vers token endpoint └─> Authorization: CLIENT SECRET └─> Body: code + code_verifier + redirect_uri 7. Reception tokens (id_token, access_token, refresh_token) └─> Encryption avec TOKEN ENCRYPTION SECRET └─> Stockage dans cookies q_session 8. Dashboard affiche └─> Session etablie └─> Utilisateur authentifie ✅ ``` --- ## 📚 References 1. **Quarkus OIDC Code Flow**: https://quarkus.io/guides/security-oidc-code-flow-authentication 2. **GitHub Issue #33532**: https://github.com/quarkusio/quarkus/issues/33532 3. **Red Hat Quarkus 3.15 OIDC**: https://docs.redhat.com/en/documentation/red_hat_build_of_quarkus/3.15/html/openid_connect_oidc_authentication/ --- ## ✅ Checklist finale - [x] Client secret recupere depuis Keycloak (32 caracteres) - [x] State secret configure pour PKCE (32 caracteres) - [x] pkce-secret=false (car state-secret est utilise) - [x] Token encryption secret configure (51 caracteres) - [x] PKCE active avec pkce-required=true - [x] Tous les secrets verifies avec verify-secrets.ps1 - [x] Documentation complete creee - [x] index.xhtml supprime pour OIDC interception - [x] Permissions HTTP configurees correctement --- **Date de resolution**: 2025-11-07 **Version Quarkus**: 3.15.1 **Configuration testee**: ✅ VALIDE **Status**: PRET POUR DEMARRAGE