Garden of KnowledgeApplied Sciences › Computer Science › Software › Security › Identity et Auth
February 25, 2026

OAuth 2.0, OIDC et SAML

OAuth 2.0 est un framework d’autorisation (délégation d’accès) — il permet à une application d’accéder à des ressources au nom d’un utilisateur sans que celui-ci ne partage ses credentials. OpenID Connect (OIDC) ajoute une couche d’authentification sur OAuth 2.0. SAML est un standard plus ancien remplissant un rôle similaire dans les environnements d’entreprise.

La danse à quatre acteurs§

OAuth résout un problème précis : “comment laisser une app tierce accéder à mes données sans lui donner mon mot de passe ?”. Quatre rôles distincts, qui interagissent dans un ordre strict.

                    ┌────────────────────────┐
                    │   Resource Owner       │
                    │   (Alice, l'utilisateur)│
                    └─────────┬──────────────┘

                              │ "Je veux laisser
                              │  l'app X accéder à
                              │  mon calendrier."

   ┌──────────────────┐                    ┌──────────────────────┐
   │  Client          │                    │ Authorization Server │
   │  (l'app X qui    │ ──── 1. redirect ──►│ (Google, Auth0,      │
   │   veut accéder)  │                    │  Keycloak, etc.)     │
   │                  │ ◄──── 2. code ──── │                      │
   │                  │ ──── 3. code  ────►│ (Alice s'authentifie │
   │                  │ ◄──── 4. token ─── │  + consent)          │
   └────────┬─────────┘                    └──────────────────────┘

            │ 5. Authorization: Bearer eyJ...

   ┌──────────────────┐
   │ Resource Server  │
   │ (Google Calendar │
   │  API)            │
   └──────────────────┘

Pourquoi quatre acteurs et pas trois ? Parce que séparer l’Authorization Server du Resource Server permet à un même Authorization Server (ex. Google) de protéger plusieurs APIs distinctes (Gmail, Drive, Calendar), et de gérer les consentements de façon centralisée. C’est aussi ce qui rend OAuth réutilisable comme système SSO via OIDC.

OAuth 2.0§

Acteurs§

RôleDescriptionExemple
Resource OwnerL’utilisateur propriétaire des donnéesAlice
ClientL’application qui demande l’accèsApplication tierce
Authorization ServerÉmet les tokens après consentementGoogle, Auth0, Keycloak
Resource ServerL’API protégéeGoogle Calendar API

Tokens§

Flows (Grant Types)§

Authorization Code + PKCE (recommandé pour apps publiques)§

1. Client → Authorization Server
   GET /authorize?
     response_type=code
     &client_id=app123
     &redirect_uri=https://app.com/callback
     &scope=openid profile email
     &state=random_csrf_token          ← protection CSRF
     &code_challenge=S256_hash         ← PKCE
     &code_challenge_method=S256

2. Utilisateur s'authentifie et consent

3. Authorization Server → Client
   GET https://app.com/callback?code=AUTH_CODE&state=random_csrf_token

4. Client → Authorization Server (échange code contre tokens)
   POST /token
   grant_type=authorization_code
   &code=AUTH_CODE
   &redirect_uri=https://app.com/callback
   &client_id=app123
   &code_verifier=PKCE_VERIFIER        ← PKCE

5. Authorization Server → Client
   {
     "access_token": "eyJ...",
     "token_type": "Bearer",
     "expires_in": 3600,
     "refresh_token": "def50200...",
     "id_token": "eyJ..."              ← OIDC uniquement
   }

6. Client → Resource Server
   GET /api/calendrier
   Authorization: Bearer eyJ...

PKCE (Proof Key for Code Exchange) : le client génère un code_verifier aléatoire, en calcule le hash SHA-256 (code_challenge), l’envoie à l’étape 1, puis prouve la possession à l’étape 4. Empêche l’interception du code d’autorisation.

Client Credentials (machine à machine)§

POST /token
grant_type=client_credentials
&client_id=service_a
&client_secret=secret
&scope=api:read

→ {"access_token": "...", "expires_in": 3600}

Pas d’utilisateur impliqué. Utilisé pour les communications entre services.

Device Authorization (appareils sans navigateur)§

1. Device → Authorization Server : demande un device_code
2. Authorization Server → Device : device_code + user_code + verification_uri
3. Device affiche : "Allez sur example.com/activate et entrez : ABCD-1234"
4. Utilisateur s'authentifie sur son téléphone/ordinateur
5. Device poll l'Authorization Server avec le device_code jusqu'à approbation

Utilisé par les Smart TV, CLI tools (GitHub CLI, AWS CLI).

Implicit et Resource Owner Password (dépréciés)§

OpenID Connect (OIDC)§

OIDC étend OAuth 2.0 avec un ID Token (JWT) qui contient des claims sur l’identité de l’utilisateur.

ID Token (JWT)§

// Header
{
  "alg": "RS256",
  "kid": "key_id_123",
  "typ": "JWT"
}

// Payload (claims)
{
  "iss": "https://accounts.google.com",   // issuer
  "sub": "110169484474386276334",          // subject (user ID unique)
  "aud": "app123.apps.googleusercontent.com",  // audience (client_id)
  "exp": 1735689600,                       // expiration
  "iat": 1735686000,                       // issued at
  "nonce": "random_nonce",                 // protection replay
  "email": "[email protected]",
  "email_verified": true,
  "name": "Alice Dupont",
  "picture": "https://..."
}

Endpoints OIDC§

# Discovery document (OpenID Configuration)
GET https://accounts.google.com/.well-known/openid-configuration
 {
    "issuer": "https://accounts.google.com",
    "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
    "token_endpoint": "https://oauth2.googleapis.com/token",
    "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
    "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs" clés publiques
  }

SAML 2.0§

SAML utilise des assertions XML signées, typiquement dans un contexte SSO entreprise (Okta, ADFS, Azure AD).

Flow SSO (SP-initiated)§

1. Utilisateur → Service Provider (SP) : accède à app.company.com
2. SP → Navigateur : redirect vers Identity Provider (IdP)
   avec SAMLRequest (XML base64 encodé)
3. Navigateur → IdP : présente le SAMLRequest
4. IdP : authentifie l'utilisateur (login/MFA)
5. IdP → Navigateur : POST vers SP avec SAMLResponse (assertion XML signée)
6. SP : valide la signature, extrait les attributs, crée la session
<!-- SAMLResponse — assertion XML signée par l'IdP -->
<saml:Assertion>
  <saml:Issuer>https://idp.company.com</saml:Issuer>
  <saml:Subject>
    <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
      [email protected]
    </saml:NameID>
  </saml:Subject>
  <saml:Conditions NotBefore="..." NotOnOrAfter="...">
    <saml:AudienceRestriction>
      <saml:Audience>https://app.company.com</saml:Audience>
    </saml:AudienceRestriction>
  </saml:Conditions>
  <saml:AttributeStatement>
    <saml:Attribute Name="groups">
      <saml:AttributeValue>admin</saml:AttributeValue>
    </saml:Attribute>
  </saml:AttributeStatement>
  <Signature>...</Signature>
</saml:Assertion>

Vulnérabilités courantes§

OAuth§

Authorization Code Interception

Si redirect_uri n'est pas strictement validée :
Attaquant redirige vers redirect_uri=https://attaquant.com/callback
→ Vole le code d'autorisation
→ Contre-mesure : PKCE, validation exacte du redirect_uri

CSRF sur le flow OAuth

Le paramètre state n'est pas validé :
Attaquant forge une URL de callback avec son propre code
→ Victime lié au compte de l'attaquant (account linking attack)
→ Contre-mesure : valider state côté client, le lier à la session

Open Redirect dans redirect_uri

GET /authorize?redirect_uri=https://app.com/callback%2F%2E%2E%2F%2E%2E%2Fattaquant.com
→ Certains serveurs acceptent les variantes URL encodées
→ Contre-mesure : whitelist stricte, pas de pattern matching

Token Leakage via Referer

Si l'access token est dans l'URL (fragment ou query) :
https://app.com/dashboard#access_token=secret
→ Le Referer header peut l'exposer
→ Contre-mesure : Authorization Code flow, tokens dans le body

SAML§

XML Signature Wrapping (XSW)

L’attaquant duplique le nœud signé et insère un nœud malveillant. Si le SP valide la signature du nœud original mais lit les attributs du nœud malveillant, il peut s’authentifier en tant qu’admin.

<!-- SAML Response modifiée par XSW -->
<saml:Assertion ID="malicious">
  <!-- attributs de l'attaquant -->
  <saml:NameID>[email protected]</saml:NameID>
</saml:Assertion>
<saml:Assertion ID="original">
  <!-- assertion originale signée (non modifiée) -->
  <saml:NameID>[email protected]</saml:NameID>
  <Signature><!-- signature valide --></Signature>
</saml:Assertion>

Commentaires XML dans NameID

<!-- Certains parseurs ignèrent les commentaires XML -->
<saml:NameID>admin<!--commentaire-->@company.com</saml:NameID>
→ Parseur A lit : "[email protected]"  (authentification admin)
→ Parseur B lit : "[email protected]"  (logique métier)

Bonnes pratiques§

PratiqueDescription
Toujours utiliser PKCEMême pour les clients confidentiels
Valider l’audience (aud)Vérifier que le token est bien destiné à votre application
Valider l’issuer (iss)Vérifier la source du token
Short-lived access tokens< 15 minutes, refresh tokens rotatifs
Stocker les tokens en mémoirePas en localStorage (XSS)
Valider state et nonceProtection CSRF et replay
Scopes minimauxPrincipe du moindre privilège

Comparatif§

DimensionOAuth 2.0OIDCSAML 2.0
ButAutorisationAuthentification + autorisationAuthentification (SSO)
Format tokenOpaque ou JWTJWT (ID Token)XML
TransportJSON/HTTPJSON/HTTPXML/HTTP POST
Cas d’usageAPI, apps mobilesLogin social, apps webSSO entreprise, ADFS
ComplexitéMoyenneMoyenneÉlevée

Pièges courants§

—The Gardener