Création de 2 écrans professionnels pour le module Devis:
1. devis/nouveau.xhtml:
- 4 sections: Informations générales, Détail du devis, Montants, Conditions
- Numéro auto-généré avec icône
- Statut avec 5 valeurs (BROUILLON, ATTENTE, ACCEPTE, REFUSE, EXPIRE)
- Dates d'émission et validité avec calendriers
- Client et objet du devis requis
- Placeholder pour lignes de devis (future développement)
- Calcul automatique TVA 18% et TTC
- Récapitulatif visuel HT/TVA/TTC avec composant monétaire
- Conditions de paiement et remarques (section collapsible)
- 3 boutons: Annuler, Brouillon, Envoyer
2. devis/details.xhtml:
- En-tête: numéro, statut, client, objet, dates
- Actions: Retour, Convertir en chantier, PDF, Modifier
- 4 KPI cards: Montant HT, TVA, TTC, Statut
- 6 onglets professionnels:
* Vue d'ensemble: infos + récap financier + actions rapides
* Détail des lignes: table lignes (placeholder)
* Conditions: paiement, délais, garanties
* Documents: GED associée (placeholder)
* Suivi: timeline actions
* Historique: modifications (placeholder)
Corrections:
- Fix navigation /factures/nouvelle -> /factures/nouveau (factures.xhtml)
- Fix menu /factures/nouvelle -> /factures/nouveau (menu.xhtml)
Tous les composants réutilisables utilisés (status-badge, monetary-display).
Validation complète côté client et serveur.
UI/UX professionnel adapté au métier BTP.
232 lines
7.4 KiB
Markdown
232 lines
7.4 KiB
Markdown
# 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
|