# 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**: ✅
