Guide d'intégration OIDC
Présentation détaillée de l'intégration de l'authentification Trousseau via le flux Authorization Code avec PKCE.
Vue d'ensemble
Trousseau implémente le flux OpenID Connect Authorization Code avec PKCE: le flux standard le plus sécurisé pour les applications web et mobiles.
Ce guide vous accompagne tout au long du flux complet, depuis la redirection de l'utilisateur vers Trousseau jusqu'à la gestion des tokens et le renouvellement des sessions.
Diagramme du flux
Votre App Trousseau (IdP)
│ │
│ 1. Générer le PKCE verifier │
│ + code_challenge │
│ │
│ 2. Redirection vers /authorize │
│ ─────────────────────────────> │
│ │
│ │ 3. L'utilisateur s'authentifie
│ │ (e-mail + mot de passe + MFA)
│ │
│ 4. Redirection vers callback │
│ avec ?code=xxx │
│ <───────────────────────────── │
│ │
│ 5. POST /token │
│ code + code_verifier │
│ ─────────────────────────────> │
│ │
│ 6. Réception des tokens │
│ (id_token, access_token, │
│ refresh_token) │
│ <───────────────────────────── │
│ │
│ 7. Valider l'id_token │
│ 8. Créer la session applicative │Endpoints
Tous les endpoints peuvent être découverts via l'URL de configuration OpenID :
GET https://auth.trousseau.app/application/o/{your-slug}/.well-known/openid-configuration| Endpoint | URL |
|---|---|
| Autorisation | https://auth.trousseau.app/application/o/authorize/ |
| Token | https://auth.trousseau.app/application/o/token/ |
| UserInfo | https://auth.trousseau.app/application/o/userinfo/ |
| JWKS | https://auth.trousseau.app/application/o/{your-slug}/jwks/ |
| End Session | https://auth.trousseau.app/application/o/{your-slug}/end-session/ |
Étape 1 : Requête d'autorisation
Redirigez l'utilisateur vers l'endpoint d'autorisation avec ces paramètres :
GET https://auth.trousseau.app/application/o/authorize/
?client_id={your-client-id}
&response_type=code
&scope=openid email profile
&redirect_uri=https://app.yourapp.com/auth/callback
&state={random-state-value}
&code_challenge={code-challenge}
&code_challenge_method=S256| Paramètre | Obligatoire | Description |
|---|---|---|
client_id | Oui | Votre client ID OIDC |
response_type | Oui | Toujours code |
scope | Oui | Scopes séparés par des espaces (openid est obligatoire) |
redirect_uri | Oui | Doit correspondre à une URI de redirection enregistrée |
state | Recommandé | Chaîne aléatoire pour prévenir les attaques CSRF |
code_challenge | Oui | Challenge PKCE (SHA-256 du code verifier, encodé en base64url) |
code_challenge_method | Oui | Toujours S256 |
Génération du PKCE
// Générer un code verifier aléatoire
const codeVerifier = crypto.randomUUID() + crypto.randomUUID();
// Créer le code challenge (hash SHA-256, encodé en base64url)
const encoder = new TextEncoder();
const digest = await crypto.subtle.digest("SHA-256", encoder.encode(codeVerifier));
const codeChallenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "");Le PKCE est obligatoire. Trousseau rejette les requêtes d'autorisation sans code_challenge valide. Cela protège contre les attaques par interception de code d'autorisation.
Étape 2 : Authentification de l'utilisateur
Trousseau affiche sa page de connexion. L'utilisateur s'authentifie avec son e-mail et son mot de passe. Si la MFA est configurée, il est invité à renseigner son second facteur.
Les nouveaux utilisateurs (sans mot de passe) sont automatiquement dirigés vers une page de création de mot de passe. Ce comportement est transparent pour votre application: vous recevez toujours le même callback.
Étape 3 : Callback d'autorisation
Après une authentification réussie, Trousseau redirige vers votre redirect_uri :
GET https://app.yourapp.com/auth/callback
?code=abc123
&state={your-state-value}Vérifiez toujours que le paramètre state correspond à la valeur envoyée à l'étape 1.
Étape 4 : Échange de tokens
Échangez le code d'autorisation contre des tokens :
POST https://auth.trousseau.app/application/o/token/
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=abc123
&redirect_uri=https://app.yourapp.com/auth/callback
&client_id={your-client-id}
&client_secret={your-client-secret}
&code_verifier={code-verifier-from-step-1}Réponse :
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 300,
"refresh_token": "eyJhbGciOi...",
"id_token": "eyJhbGciOi...",
"scope": "openid email profile"
}Étape 5 : Validez l'ID token
L'id_token est un JWT contenant les claims de l'utilisateur. Avant de lui faire confiance :
- Vérifiez la signature via l'endpoint JWKS
- Vérifiez
isscorrespond à votre URL d'émetteur - Vérifiez
audcorrespond à votre client ID - Vérifiez
expest dans le futur - Vérifiez
noncesi vous en avez envoyé un (optionnel)
La plupart des bibliothèques OIDC gèrent cette validation automatiquement.
Exemple d'ID token décodé
{
"iss": "https://auth.trousseau.app/application/o/your-slug/",
"sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"aud": "your-slug-oidc",
"exp": 1712400000,
"iat": 1712399700,
"email": "jean.dupont@hotel.com",
"email_verified": true,
"name": "Jean Dupont",
"given_name": "Jean",
"family_name": "Dupont",
"picture": "https://auth.trousseau.app/media/avatars/..."
}Étape 6 : Renouvellement des tokens
Les access tokens expirent après 5 minutes. Utilisez le refresh token pour en obtenir de nouveaux sans que l'utilisateur ait à se réauthentifier :
POST https://auth.trousseau.app/application/o/token/
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token={refresh-token}
&client_id={your-client-id}
&client_secret={your-client-secret}Réponse : Même format que la réponse d'échange de tokens, avec de nouveaux tokens.
Les refresh tokens sont valides pendant 30 jours. Après expiration, l'utilisateur doit se réauthentifier via le flux d'autorisation.
Gestion des erreurs
Erreurs d'autorisation
Si l'authentification échoue ou si l'utilisateur refuse l'accès, Trousseau redirige vers votre callback avec une erreur :
GET https://app.yourapp.com/auth/callback
?error=access_denied
&error_description=User denied access
&state={your-state-value}Codes d'erreur courants :
| Erreur | Signification |
|---|---|
access_denied | L'utilisateur n'appartient pas au groupe d'accès de votre application |
invalid_scope | Vous avez demandé un scope non autorisé pour votre application |
server_error | Erreur interne: réessayez ou contactez le support |
Erreurs de token
| Erreur | Signification |
|---|---|
invalid_grant | Code d'autorisation expiré ou déjà utilisé |
invalid_client | Client ID ou secret incorrect |
invalid_request | Paramètre obligatoire manquant |