OAuth 2.1 consolide les meilleures pratiques de sécurité OAuth 2.0 en une spécification unifiée : PKCE obligatoire pour tous les clients, suppression de l'implicit flow et du password grant, refresh token rotation activé par défaut. Pour les équipes IAM et les développeurs, cette migration n'est pas optionnelle — elle corrige des vulnérabilités structurelles exploitées activement en 2025-2026.

Le projet de spécification OAuth 2.1 (draft-ietf-oauth-v2-1) marque une rupture nette avec les ambiguïtés qui ont fragilisé les déploiements OAuth 2.0 depuis 2012. Alors que les audits IAM révèlent encore en 2026 des applications exposant des access tokens dans des URL fragments, des refresh tokens non rotés depuis des années, et des redirect URIs validées avec des wildcards permissifs, OAuth 2.1 impose des protections qui étaient jusqu'ici optionnelles ou mal appliquées. Maîtriser les exigences de l'oauth 2.1 protections migration 2026 est désormais une priorité pour tout architecte sécurité : PKCE devient obligatoire même pour les clients confidentiels, l'implicit flow disparaît définitivement, le Resource Indicator (RFC 8707) permet d'adresser des audiences multiples sans confusion de token, et les Pushed Authorization Requests (RFC 9126) éliminent une classe entière d'attaques CSRF sur les endpoints d'autorisation. Cet article décrypte chaque changement structurel de la spécification, compare OAuth 2.0 et OAuth 2.1 sur dix critères techniques, fournit du code fonctionnel en Python et Node.js, et guide la migration étape par étape depuis les configurations héritées vers les nouveaux standards de sécurité IAM.

À retenir

  • PKCE obligatoire : OAuth 2.1 impose PKCE (S256) pour tous les clients, publics et confidentiels — aucune exception n'est tolérée.
  • Implicit flow supprimé : les tokens ne sont plus jamais exposés dans des URL fragments, éliminant une surface d'attaque XSS structurelle majeure.
  • Refresh token rotation : chaque usage d'un refresh token en génère un nouveau ; la détection automatique de réutilisation invalide la famille de tokens entière.
  • PAR (RFC 9126) : les paramètres d'autorisation sont pré-enregistrés côté serveur via un endpoint dédié en back-channel, éliminant la manipulation en transit.
  • FAPI 2.0 : profil financier basé sur OAuth 2.1 + PAR + DPoP, désormais requis par plusieurs régulateurs européens pour les APIs open banking.

PKCE : de recommandation optionnelle à exigence absolue dans OAuth 2.1

Le Proof Key for Code Exchange (PKCE, RFC 7636) a été conçu en 2015 pour protéger les clients publics — applications mobiles et Single Page Applications — contre les attaques par interception du code d'autorisation. Dans OAuth 2.1, PKCE devient obligatoire pour tous les clients, y compris les clients confidentiels capables de stocker un client_secret. La raison est simple : PKCE défend contre l'interception du code, une attaque qui ne dépend pas du type de client.

Le mécanisme repose sur un défi cryptographique en cinq étapes :

  1. Le client génère un code_verifier : chaîne aléatoire de 43 à 128 caractères encodée en Base64URL, avec une entropie minimale de 256 bits.
  2. Le client calcule le code_challenge via BASE64URL(SHA256(ASCII(code_verifier))) avec la méthode S256.
  3. Le code_challenge est transmis au serveur d'autorisation dans la requête initiale.
  4. Lors de l'échange du code contre un token, le client envoie le code_verifier original en clair.
  5. Le serveur recalcule le hash et vérifie qu'il correspond au code_challenge stocké en session.

Un attaquant interceptant le code d'autorisation ne peut pas l'échanger sans connaître le code_verifier, qui n'a jamais transité sur le canal exposé. La méthode plain (sans hachage) est explicitement interdite dans OAuth 2.1 — seul S256 est autorisé.

import hashlib
import base64
import secrets
import urllib.parse
import requests

# Generation du code_verifier (RFC 7636, section 4.1)
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b'=').decode('ascii')

# Calcul du code_challenge S256 (seule methode autorisee en OAuth 2.1)
digest = hashlib.sha256(code_verifier.encode('ascii')).digest()
code_challenge = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii')

# Parametres de la requete d'autorisation
auth_params = {
    'response_type': 'code',
    'client_id': 'mon-app-client',
    'redirect_uri': 'https://app.example.com/callback',
    'scope': 'openid profile email',
    'state': secrets.token_urlsafe(16),
    'code_challenge': code_challenge,
    'code_challenge_method': 'S256',  # obligatoire, plain interdit
}

auth_url = 'https://auth.example.com/authorize?' + urllib.parse.urlencode(auth_params)
print(f"URL d'autorisation : {auth_url}")

# Echange du code contre un token (token endpoint)
def exchange_code_for_token(authorization_code, redirect_uri, client_id, client_secret=None):
    token_data = {
        'grant_type': 'authorization_code',
        'code': authorization_code,
        'redirect_uri': redirect_uri,
        'client_id': client_id,
        'code_verifier': code_verifier,  # verificateur original, jamais expose avant
    }
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    auth = (client_id, client_secret) if client_secret else None
    response = requests.post(
        'https://auth.example.com/token',
        data=token_data,
        headers=headers,
        auth=auth
    )
    return response.json()

Implicit Flow et Password Grant : pourquoi OAuth 2.1 les supprime-t-il définitivement ?

L'implicit flow retournait l'access token directement dans le fragment d'URL de la redirection (#access_token=eyJ...&token_type=bearer). Cette approche présentait trois problèmes structurels non corrigibles sans changer le flow lui-même :

  • Exposition XSS immédiate : tout script injecté dans la page de callback pouvait lire le token via window.location.hash, sans contourner aucune Same-Origin Policy.
  • Fuite dans les logs et l'historique : les fragments URL apparaissent dans l'historique du navigateur, les logs de proxy d'entreprise, les headers Referer vers des ressources tierces (analytics, CDN d'images).
  • Absence de refresh token : l'implicit flow ne permettait pas d'émettre des refresh tokens, forçant des re-authentifications fréquentes ou des durées de vie d'access token excessivement longues.

Le Resource Owner Password Credentials grant (ROPC) — qui permettait à une application tierce de collecter directement le couple login/mot de passe de l'utilisateur pour obtenir un token en son nom — est également supprimé. Il contrevenait au principe fondamental d'OAuth (délégation d'autorisation sans partage de credentials) et exposait les mots de passe à des intermédiaires non nécessaires, incompatible avec la détection de phishing et les mécanismes MFA modernes.

Les SPAs et applications mobiles utilisent désormais exclusivement l'Authorization Code Flow avec PKCE : pas de client_secret requis, protection PKCE robuste, refresh tokens supportés, et compatibilité complète avec les navigateurs modernes via CORS sur le token endpoint.

Refresh Token Rotation : comment fonctionne la détection automatique du vol de token ?

Dans OAuth 2.1, la rotation des refresh tokens est le comportement attendu par défaut. Le principe est simple : chaque utilisation d'un refresh token génère un nouveau refresh token et invalide immédiatement l'ancien. Un mécanisme de détection de vol — la Refresh Token Family Invalidation — est fortement recommandé par la spécification :

  1. Le serveur associe chaque refresh token à une "famille" identifiée par un UUID de session initiale.
  2. Un token révoqué est marqué mais conservé en base de données avec son statut.
  3. Si un refresh token déjà révoqué est présenté à nouveau, le serveur conclut qu'un attaquant possède une copie : il invalide immédiatement toute la famille de tokens.
  4. L'utilisateur légitime — qui ne dispose plus de refresh token valide — est forcé à se ré-authentifier interactivement.

Cette approche est supérieure à la simple invalidation séquentielle car elle détecte le cas où l'attaquant a utilisé le token avant l'utilisateur légitime — situation dans laquelle l'utilisateur se retrouve avec un token révoqué sans comprendre pourquoi. L'événement déclenche une alerte de sécurité : vol de refresh token confirmé.

Pour les refresh tokens à longue durée de vie, OAuth 2.1 recommande des durées combinées : une durée absolue maximale (ex : 30 jours) ET une durée d'inactivité (ex : 7 jours sans utilisation). Un token inactif expire même si la fenêtre absolue n'est pas écoulée.

PAR (Pushed Authorization Requests) : sécuriser l'endpoint d'autorisation en back-channel

Les Pushed Authorization Requests (RFC 9126) résolvent un problème longtemps sous-estimé : dans le flow standard, les paramètres d'autorisation — redirect_uri, scope, state, code_challenge — transitent dans l'URL du navigateur, exposés aux extensions, proxies, et potentiellement manipulables par l'utilisateur ou des scripts tiers.

Avec PAR, le client envoie ses paramètres directement au serveur d'autorisation via un endpoint dédié (/par) en HTTPS back-channel avant même de rediriger l'utilisateur. Le serveur valide l'intégralité de la requête et retourne un request_uri opaque à courte durée de vie (typiquement 60 secondes). Le client redirige ensuite l'utilisateur avec uniquement ce request_uri :

// Node.js — Authorization Code Flow avec PAR et PKCE
const crypto = require('crypto');
const axios = require('axios');

async function initiateAuthWithPAR(clientId, clientSecret, redirectUri, scope) {
  // 1. Generer le code_verifier et code_challenge PKCE
  const codeVerifier = crypto.randomBytes(32).toString('base64url');
  const codeChallenge = crypto
    .createHash('sha256')
    .update(codeVerifier)
    .digest('base64url');

  const state = crypto.randomBytes(16).toString('base64url');

  // 2. Pushed Authorization Request (back-channel, HTTPS direct vers le serveur)
  const parResponse = await axios.post(
    'https://auth.example.com/par',
    new URLSearchParams({
      response_type: 'code',
      client_id: clientId,
      redirect_uri: redirectUri,
      scope: scope,
      state: state,
      code_challenge: codeChallenge,
      code_challenge_method: 'S256',
    }),
    {
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      auth: { username: clientId, password: clientSecret },
    }
  );

  const { request_uri, expires_in } = parResponse.data;
  console.log(`PAR valide cote serveur. request_uri expire dans ${expires_in}s`);

  // 3. Redirection utilisateur avec uniquement le request_uri opaque
  const authUrl = new URL('https://auth.example.com/authorize');
  authUrl.searchParams.set('client_id', clientId);
  authUrl.searchParams.set('request_uri', request_uri);

  return { authUrl: authUrl.toString(), codeVerifier, state };
}

L'avantage sécurité est double : les paramètres sensibles ne transitent jamais dans les URLs exposées au navigateur, et le serveur peut rejeter une requête invalide avant que l'utilisateur ne soit impliqué dans le flow. FAPI 2.0 impose PAR comme exigence obligatoire sans exception.

Resource Indicator et Device Authorization Grant : cas d'usage avancés

Le Resource Indicator (RFC 8707) résout le problème de l'audience confusion dans les architectures multi-API. Sans ce mécanisme, un access token obtenu pour l'API de comptabilité peut théoriquement être présenté à l'API RH si les deux partagent le même serveur d'autorisation — les deux acceptent des tokens du même émetteur. Le Resource Indicator permet au client de spécifier explicitement quelle(s) ressource(s) il souhaite adresser :

{
  "response_type": "code",
  "client_id": "erp-frontend",
  "resource": "https://api.example.com/comptabilite",
  "scope": "read:factures write:factures",
  "code_challenge": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
  "code_challenge_method": "S256"
}

Le serveur intègre l'URL de la ressource dans le claim aud du JWT access token. L'API de comptabilité vérifie que son URL correspond à l'aud et rejette tout token émis pour une autre ressource, même parfaitement signé par ailleurs.

Le Device Authorization Grant (RFC 8628, intégré dans OAuth 2.1) cible les dispositifs sans navigateur interactif ou sans clavier : téléviseurs connectés, consoles de jeu, imprimantes réseau, équipements IoT industriels, CLI d'outils DevOps comme Terraform ou kubectl. Le flow en trois phases évite toute saisie de credentials sur l'appareil lui-même :

  1. L'appareil demande un device_code et un user_code court (ex : ABCD-1234) au token endpoint via une requête POST simple.
  2. L'utilisateur saisit le user_code sur un appareil secondaire (smartphone, PC) en visitant l'URL de vérification affichée à l'écran de l'appareil.
  3. L'appareil poll l'endpoint token à intervalle régulier (5 secondes recommandé) jusqu'à recevoir l'autorisation ou un timeout configuré.

JWT Validation : les vérifications incontournables pour chaque access token

Un access token JWT mal validé constitue une vulnérabilité critique indépendante de la qualité du flow d'autorisation en amont. OAuth 2.1 impose un ensemble minimal de vérifications à effectuer par chaque API protégée à chaque requête entrante reçue :

  • iss (issuer) : doit correspondre exactement à l'URL canonique du serveur d'autorisation de confiance — comparaison stricte, aucune normalisation d'URL permise.
  • aud (audience) : doit inclure l'identifiant de l'API qui valide le token. Un token émis pour une autre audience doit être rejeté même s'il est signé valablement.
  • exp (expiration) : le timestamp Unix doit être dans le futur avec une tolérance d'horloge maximale de 30 secondes recommandée.
  • nbf (not before) : si présent, le token n'est pas valide avant ce timestamp — critique pour les tokens pré-émis en batch.
  • jti (JWT ID) : identifiant unique du token. Maintenir une liste de jti consommés (cache Redis avec TTL égal à la durée de vie du token) permet de détecter les attaques par rejeu.
import jwt
from jwt import PyJWKClient

# Recuperation et cache automatique des cles publiques via JWKS
jwks_client = PyJWKClient(
    'https://auth.example.com/.well-known/jwks.json',
    cache_keys=True,
    lifespan=3600
)

def validate_access_token(token: str, expected_audience: str, expected_issuer: str) -> dict:
    # Recuperation de la cle de signature correspondant au kid du header JWT
    signing_key = jwks_client.get_signing_key_from_jwt(token)

    payload = jwt.decode(
        token,
        signing_key.key,
        algorithms=["RS256", "ES256"],  # algorithmes symetriques (HS256) interdits
        audience=expected_audience,
        issuer=expected_issuer,
        options={
            "require": ["exp", "iss", "aud", "iat", "jti"],
            "verify_exp": True,
            "verify_iat": True,
            "leeway": 30  # tolerance horloge en secondes
        }
    )

    # Detection de rejeu : verifier le jti contre un cache Redis
    if is_jti_seen(payload['jti'], payload['exp']):
        raise jwt.InvalidTokenError(f"Token replay detecte : jti={payload['jti']}")

    return payload

def is_jti_seen(jti: str, exp: int) -> bool:
    # Redis : SET jti:{jti} 1 EXAT {exp} NX
    # NX = seulement si absent (retourne None si cree, erreur si existant = rejeu)
    return False  # implementer selon le volume de trafic

FAPI 2.0 : le profil OAuth 2.1 pour le secteur financier et réglementé

La Financial-grade API Security Profile 2.0 (FAPI 2.0), développée par l'OpenID Foundation, répond aux exigences des régulateurs financiers : PSD2/DSP2 en Europe, CDR en Australie, Open Finance au Brésil. FAPI 2.0 se construit sur OAuth 2.1 et impose des contraintes supplémentaires adaptées aux transactions à haute valeur :

  • PAR obligatoire : aucune requête d'autorisation n'est acceptée sans passer par l'endpoint PAR — les paramètres ne transitent jamais dans le navigateur.
  • DPoP (RFC 9449 — Demonstrating Proof of Possession) : les tokens sont liés cryptographiquement à la clé privée du client. Un token volé est inutilisable sans la clé privée associée au moment de l'émission.
  • JARM (JWT Secured Authorization Response Mode) : les réponses d'autorisation sont signées par le serveur d'autorisation, empêchant la manipulation des paramètres code et state dans la redirection de retour.
  • mTLS (RFC 8705) : authentification client par certificat TLS mutuel sur le token endpoint, en remplacement ou complément du client_secret pour les clients confidentiels critiques.

En France, l'ANSSI référence les profils FAPI dans ses recommandations sur l'authentification forte pour les applications exposant des données sensibles. Les APIs bancaires françaises conformes à la DSP2 imposent FAPI 2.0 aux Third Party Providers (TPP) depuis 2025. Consultez les recommandations officielles sur cyber.gouv.fr pour les exigences spécifiques au secteur public français.

Comparatif OAuth 2.0 vs OAuth 2.1 : 10 critères essentiels

Critère OAuth 2.0 (RFC 6749) OAuth 2.1 (draft-ietf-oauth-v2-1)
PKCE Recommandé pour clients publics uniquement Obligatoire pour tous les clients (S256 exclusivement)
Implicit Flow Supporté (officiellement déconseillé depuis 2019) Supprimé de la spécification
Password Grant (ROPC) Supporté comme grant type standard Supprimé de la spécification
Refresh Token Rotation Optionnelle, rarement configurée Comportement attendu par défaut, family invalidation recommandée
Redirect URI Matching Wildcards parfois tolérés par les serveurs Comparaison exacte de chaîne obligatoire, aucun wildcard
Pushed Authorization Requests Non défini (extension externe RFC 9126) Extension intégrée, requise par FAPI 2.0
Resource Indicators Non défini (extension externe RFC 8707) Extension intégrée, recommandée pour architectures multi-API
Device Authorization Grant Extension externe RFC 8628 Intégré comme grant type reconnu dans la spécification
Validation redirect_uri Implémentations variables, open redirect fréquents Strict string comparison, path traversal et wildcards interdits
Token Binding Bearer tokens sans binding (vol = usage immédiat possible) DPoP supporté pour lier le token à la clé cryptographique du client

Guide de migration OAuth 2.0 vers OAuth 2.1 : par où commencer ?

La migration vers OAuth 2.1 ne requiert pas de refonte architecturale si l'infrastructure OAuth 2.0 existante utilise déjà l'Authorization Code Flow. Les étapes sont ordonnées par urgence sécuritaire et impact sur les applications existantes :

Étape 1 — Audit des flows actifs

Analyser les logs du serveur d'autorisation pour identifier toutes les requêtes avec response_type=token (implicit flow) ou grant_type=password (ROPC). Ces applications sont les seules à nécessiter une réécriture obligatoire. Pour les applications mobiles utilisant ROPC, la migration vers Authorization Code Flow avec PKCE via AppAuth (Android/iOS) prend généralement 1 à 3 jours de développement.

Étape 2 — Activer PKCE sur tous les clients

Les bibliothèques OAuth modernes supportent PKCE nativement : authlib et requests-oauthlib en Python, passport.js avec stratégie OAuth2 en Node.js, AppAuth pour les applications natives iOS et Android. L'ajout côté client représente une modification de 5 à 15 lignes de code. Côté serveur d'autorisation, vérifier le support PKCE et configurer la vérification comme obligatoire dès que tous les clients sont migrés.

Étape 3 — Corriger la validation des redirect URIs

Auditer la configuration de chaque client enregistré pour éliminer tous les wildcards et patterns de correspondance partielle. Chaque environnement (développement, staging, production) doit avoir ses propres URIs exactes déclarées dans des clients distincts. Un inventaire des clients OAuth avec leurs URIs actuelles est la première livrable de cette étape.

Étape 4 — Déployer la rotation des refresh tokens

Configurer le serveur d'autorisation pour émettre un nouveau refresh token à chaque usage et invalider l'ancien immédiatement. Implémenter la détection de réutilisation de token révoqué avec invalidation de famille. Ajuster les durées de vie selon la sensibilité : access token 5 à 15 minutes, refresh token 7 à 30 jours avec expiration par inactivité.

Étape 5 — Déployer PAR pour les applications critiques

Commencer par les applications traitant des données personnelles sensibles, des transactions financières, ou des accès administrateurs. Keycloak 21+, Auth0 Enterprise, Okta en configuration avancée, ForgeRock AM et PingFederate supportent RFC 9126 nativement. Cette étape peut être progressive sans affecter les applications non migrées.

Pour approfondir la sécurisation de votre infrastructure IAM, consultez notre guide sur les Abus OAuth/OIDC : Consent Abuse et manipulation de consentement, ainsi que notre article sur le déploiement Zero Trust sur Microsoft 365. L'intégration avec des politiques de durcissement des serveurs d'autorisation — désactivation des endpoints non utilisés, CORS restrictif, rate limiting sur le token endpoint — complète le dispositif de sécurité OAuth.

Failles structurelles corrigées par OAuth 2.1 : analyse technique

OAuth 2.1 cristallise les correctifs apportés par plusieurs années de CVEs, de retours de pentests et de recommandations du groupe de travail IETF OAuth :

Redirect URI Validation (CWE-601 — Open Redirect) : OAuth 2.0 tolérait une validation partielle des redirect URIs — correspondance par préfixe, usage de wildcards, normalisation d'URL non stricte. Des attaquants enregistraient des URIs comme https://app.example.com.evil.com/callback ou exploitaient des path traversal (https://app.example.com/callback/../malicious) quand la validation ne vérifiait que le domaine racine. OAuth 2.1 impose une comparaison exacte de la chaîne complète, sans aucune normalisation.

Authorization Code Interception Attack : sans PKCE, un attaquant capable d'intercepter le code d'autorisation — malware sur mobile exploitant un URI scheme partagé entre applications, extension de navigateur malveillante, log de proxy d'entreprise — pouvait l'échanger directement contre un access token. PKCE obligatoire neutralise entièrement cette classe d'attaque : sans le code_verifier, le code intercepté est inutilisable.

Token Leakage via Referer Header : l'implicit flow exposait des access tokens dans les URL fragments, qui pouvaient fuir vers des ressources tierces via le header HTTP Referer (trackers analytics JavaScript, polices hébergées sur CDN externe, pixels de suivi). La suppression de l'implicit flow ferme définitivement ce canal d'exfiltration passive souvent ignoré.

Mix-Up Attacks : dans les environnements multi-IdP, un attaquant en position de man-in-the-browser pouvait rediriger une requête d'autorisation vers un IdP malveillant pour récupérer un code d'autorisation réel destiné à l'IdP légitime. OAuth 2.1 intègre le paramètre iss dans les réponses d'autorisation (RFC 9207) pour que le client vérifie que la réponse provient bien de l'IdP attendu.

Dans le contexte de la Sécurité des Agents IA en Production, ces protections OAuth sont critiques : les pipelines d'agents IA utilisent fréquemment OAuth pour l'autorisation inter-services, et une implémentation défaillante expose l'ensemble du pipeline à des escalades de privilèges inter-agents. Les plateformes de Cyber-Défense et Threat Hunting détectent désormais les anomalies OAuth — bursts de refresh tokens, codes d'autorisation présentés plusieurs fois, redirect URIs inhabituelles — comme signatures de compromission de première classe dans les SIEM.

Compatibilité des Identity Providers majeurs en 2026

La prise en charge d'OAuth 2.1 varie selon les plateformes, mais les fonctionnalités essentielles sont disponibles sur tous les fournisseurs enterprise majeurs :

  • Keycloak 24+ : support complet PAR (RFC 9126), PKCE S256 obligatoire configurable par realm, profil FAPI 2.0 disponible et certifié, rotation des refresh tokens native depuis Keycloak 18, DPoP en preview depuis Keycloak 23.
  • Auth0 / Okta Customer Identity : PKCE activé par défaut sur toutes les nouvelles applications SPA depuis 2022, PAR disponible en tier Enterprise, rotation des refresh tokens configurable par application avec détection de réutilisation intégrée.
  • Microsoft Entra ID : PKCE recommandé et supporté sur toutes les applications enregistrées, implicit flow désactivable par politique de tenant, PAR en public preview depuis fin 2025, mTLS disponible pour les clients confidentiels critiques.
  • ForgeRock AM / PingFederate : FAPI 2.0 certifiés OpenID Foundation, PAR et DPoP disponibles nativement, déploiements open banking avec JARM et mTLS opérationnels en production dans plusieurs banques européennes.

La spécification complète est disponible sur oauth.net/2.1. Le profil financier FAPI 2.0 est documenté sur openid.net/specs/fapi/2.0. Le cadre d'assurance d'identité NIST SP 800-63B, référence complémentaire pour les niveaux d'assurance AAL1/AAL2/AAL3 compatibles avec OAuth 2.1, est accessible sur pages.nist.gov/800-63-4.

Questions fréquentes

OAuth 2.1 est-il rétrocompatible avec OAuth 2.0 ?

Partiellement. Les applications utilisant l'Authorization Code Flow avec PKCE sont déjà conformes à OAuth 2.1 sans modification. La migration devient obligatoire uniquement pour les applications utilisant l'implicit flow, le ROPC grant, ou des redirect URIs avec wildcards. La majorité des bibliothèques OAuth modernes supportent déjà toutes les exigences OAuth 2.1, rendant la migration principalement une question de configuration plutôt que de réécriture de code applicatif.

Quelle est la différence concrète entre PKCE et un client_secret ?

Un client_secret est une valeur statique partagée entre le client et le serveur, stockée dans l'application — elle peut être extraite par reverse engineering d'une application mobile ou d'une SPA minifiée. Le code_verifier PKCE est généré dynamiquement pour chaque transaction, n'est jamais stocké durablement au-delà du flow en cours, et ne vaut que pour l'échange de ce code précis. Les deux mécanismes sont complémentaires : PKCE lie la transaction au client initiateur, le client_secret identifie l'application côté serveur.

Comment OAuth 2.1 interagit-il avec OpenID Connect ?

OpenID Connect reste pleinement compatible avec OAuth 2.1 — OIDC est une couche d'identité construite sur OAuth et adopte naturellement ses évolutions de sécurité. PKCE s'applique aux flows OIDC de la même façon qu'aux flows OAuth purs, PAR s'applique aux requêtes d'authentification OIDC, et les validations JWT s'appliquent à la fois aux access tokens OAuth et aux ID tokens OIDC. Migrer vers OAuth 2.1 améliore donc simultanément la posture de sécurité OIDC sans travail supplémentaire.

PAR est-il nécessaire si on utilise déjà PKCE et un client_secret ?

PKCE et PAR répondent à des menaces différentes et complémentaires. PKCE protège contre l'interception du code d'autorisation après émission. PAR protège les paramètres de la requête d'autorisation eux-mêmes en les soustrayant au canal navigateur avant que l'utilisateur ne soit redirigé, et permet au serveur de valider et rejeter une requête invalide en amont. Pour les applications à haute sensibilité traitant des données financières, médicales ou d'accès administrateur, les deux mécanismes doivent être déployés conjointement.

Quand OAuth 2.1 sera-t-il finalisé comme RFC officielle ?

Le draft OAuth 2.1 (draft-ietf-oauth-v2-1) est en cours de finalisation à l'IETF depuis 2020. La RFC officielle n'est pas encore publiée mi-2026, mais le contenu technique de la spécification est stable et considéré comme figé par l'IETF OAuth Working Group. Les principaux Identity Providers et bibliothèques ont implémenté les exigences sans attendre la publication formelle. Les organisations peuvent et doivent migrer dès maintenant — la finalisation est une procédure administrative, pas un signal technique d'attendre.