# Configuration des Secrets OIDC - BTPXpress Client JSF ## ✅ Solution définitive au problème "Secret key for encrypting state cookie is less than 16 characters long" ### Problème identifié Quarkus OIDC nécessite **TROIS secrets différents** pour fonctionner correctement avec PKCE et client confidential: 1. **Client Secret** - Pour l'authentification auprès de Keycloak 2. **State Secret** - Pour encrypter le PKCE code verifier dans le state cookie 3. **Token Encryption Secret** - Pour encrypter les tokens dans les cookies de session ### ❌ Erreur rencontrée ``` io.quarkus.runtime.configuration.ConfigurationException: Secret key for encrypting state cookie is less than 16 characters long ``` ### 🔍 Cause racine Quand `quarkus.oidc.authentication.pkce-required=true` est activé, Quarkus a besoin d'un **state-secret de 32 caractères** pour encrypter le PKCE code verifier dans le state cookie. Ce secret est: - Auto-généré si le client secret fait au moins 32 caractères ET n'est pas explicitement configuré - **OBLIGATOIRE à configurer explicitement** si le fallback au client secret ne fonctionne pas ### ✅ Configuration finale dans application.properties ```properties # 1. Client Secret (32 caractères) - Récupéré depuis Keycloak quarkus.oidc.credentials.secret=0Ph4e31lQQuonodmLQG3JycehbFL1Hei # 2. PKCE avec State Secret (32 caractères) - OBLIGATOIRE quarkus.oidc.authentication.pkce-required=true # pkce-secret=false car on utilise un state-secret dédié (pas le client secret) quarkus.oidc.authentication.pkce-secret=false quarkus.oidc.authentication.state-secret=btpxpress-pkce-state-secret-32ch # 3. Token Encryption Secret (32+ caractères) - Pour les cookies de session 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 récapitulatif des secrets | Secret | Propriété | Longueur | Valeur | Usage | |--------|-----------|----------|--------|-------| | Client Secret | `quarkus.oidc.credentials.secret` | 32 chars | `0Ph4e31lQQuonodmLQG3JycehbFL1Hei` | Authentification avec Keycloak | | State Secret | `quarkus.oidc.authentication.state-secret` | 32 chars | `btpxpress-pkce-state-secret-32c` | Encryption PKCE code verifier | | Token Encryption | `quarkus.oidc.token-state-manager.encryption-secret` | 32+ chars | `btpxpress-secure-cookie-encryption-key-32chars-2025` | Encryption tokens dans cookies | ## 🎯 Pourquoi ces 3 secrets? ### 1. Client Secret (credentials.secret) - **Rôle**: Authentifie l'application auprès de Keycloak lors de l'échange du code d'autorisation - **Requis pour**: Client confidential (non public) - **Source**: Généré par Keycloak et récupéré via script `get-client-secret.ps1` ### 2. State Secret (authentication.state-secret) - **Rôle**: Encrypte le PKCE code verifier stocké dans le state cookie pendant la redirection OIDC - **Requis pour**: PKCE (`pkce-required=true`) - **Important**: Si `state-secret` est défini, il faut mettre `pkce-secret=false`. Si `pkce-secret=true`, le client secret est utilisé et state-secret ne doit PAS être configuré - **Documentation**: [Quarkus OIDC Code Flow Authentication](https://quarkus.io/guides/security-oidc-code-flow-authentication) ### 3. Token Encryption Secret (token-state-manager.encryption-secret) - **Rôle**: Encrypte les tokens ID, access et refresh stockés dans les cookies de session - **Requis pour**: Déploiements multi-pods ou quand la taille des cookies dépasse 4096 bytes - **Documentation**: [Quarkus OIDC Expanded Configuration](https://quarkus.io/guides/security-oidc-expanded-configuration) ## 🔐 Sécurité en production ### ⚠️ IMPORTANT: Ne jamais commiter les secrets en production! Pour la production, utilisez des variables d'environnement: ```properties # production-application.properties quarkus.oidc.credentials.secret=${KEYCLOAK_CLIENT_SECRET} quarkus.oidc.authentication.state-secret=${OIDC_STATE_SECRET} quarkus.oidc.token-state-manager.encryption-secret=${OIDC_TOKEN_ENCRYPTION_SECRET} ``` ### Génération de secrets sécurisés ```bash # Linux/Mac openssl rand -base64 32 # PowerShell -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 32 | ForEach-Object {[char]$_}) # Python python -c "import secrets; print(secrets.token_urlsafe(32)[:32])" ``` ## 📚 Références officielles 1. **GitHub Issue #33532**: [Clarify startup warning: Secret key for encrypting](https://github.com/quarkusio/quarkus/issues/33532) 2. **Quarkus Guide**: [OpenID Connect authorization code flow](https://quarkus.io/guides/security-oidc-code-flow-authentication) 3. **Red Hat Documentation**: [OpenID Connect (OIDC) authentication - Quarkus 3.15](https://docs.redhat.com/en/documentation/red_hat_build_of_quarkus/3.15/html/openid_connect_oidc_authentication/) ## ✅ Vérification de la configuration Pour vérifier que tous les secrets sont correctement configurés: ```bash # Démarrer l'application mvn quarkus:dev # Vérifier les logs - vous devriez voir: # ✓ OIDC enabled # ✓ Discovered OIDC endpoints from https://security.lions.dev/realms/btpxpress/.well-known/openid-configuration # ✓ Aucune erreur "Secret key for encrypting state cookie" ``` ## 🧪 Test du flux OIDC 1. Accéder à `http://localhost:8081` 2. → Redirection automatique vers `https://security.lions.dev` 3. → Connexion avec utilisateur existant (admin@btpxpress.dev, etc.) 4. → Validation PKCE code verifier (encrypté avec state-secret) 5. → Échange authorization code contre tokens (avec client secret) 6. → Stockage tokens dans cookies (encryptés avec token-encryption-secret) 7. → Redirection vers `/dashboard.xhtml` ✅ --- **Date de résolution**: 2025-11-07 **Version Quarkus**: 3.15.1 **Configuration testée et validée**: ✅