Chapitre 615 minIntermédiaire
OAuth 2.0, OpenID Connect, SAML : l'authentification unique (SSO)
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- expliquer ce qu'apporte et ce que risque l'authentification unique ;
- distinguer OAuth 2.0, OpenID Connect et SAML ;
- décrire le flux du code d'autorisation avec PKCE ;
- vérifier un ID token et éviter les erreurs d'intégration.
4 exercices corrigés1 schéma
L'authentification unique, ou SSO (Single Sign-On), permet à un utilisateur de s'authentifier une seule fois auprès d'un fournisseur d'identité pour accéder ensuite à plusieurs applications sans retaper son mot de passe. Trois protocoles la rendent possible sur le web : OAuth 2.0, qui délègue une autorisation d'accès à une API ; OpenID Connect, qui ajoute à OAuth 2.0 la preuve de l'identité de l'utilisateur ; et SAML 2.0, plus ancien, très présent dans les entreprises. Ce chapitre explique leurs rôles, le parcours d'une connexion et les erreurs d'intégration à éviter.
Ce que l'authentification unique change
Sans SSO, chaque application gère ses propres comptes : l'utilisateur jongle avec dix mots de passe, le service informatique désactive dix comptes au départ d'un salarié (et en oublie un). Avec le SSO, les applications délèguent l'authentification à un fournisseur d'identité (Identity Provider, IdP), qui vérifie le mot de passe et la MFA puis leur transmet une preuve signée.
| Avantages | Risques |
|---|---|
| Un seul mot de passe, donc un mot de passe plus long et mieux protégé | Un compte compromis ouvre toutes les applications |
| La MFA déployée une fois, au même endroit, pour toutes les applications | Si le fournisseur d'identité tombe, plus personne ne se connecte nulle part |
| Un départ se traite en désactivant un seul compte | Une erreur de configuration du fournisseur touche tout le système d'information |
| Les journaux de connexion sont centralisés | Les applications doivent vérifier correctement les jetons reçus |
Le vocabulaire
| Terme | Rôle | Exemple |
|---|---|---|
| Fournisseur d'identité (IdP, OpenID Provider en OIDC) | Authentifie l'utilisateur et émet les jetons ou assertions | Keycloak, Microsoft Entra ID, LemonLDAP::NG, FranceConnect |
| Fournisseur de service (SP en SAML), partie de confiance ou client (OIDC) | L'application qui fait confiance au fournisseur d'identité | L'intranet, l'outil de tickets, l'application de paie |
| Fédération d'identité | Relation de confiance entre organisations : les comptes de l'une sont acceptés par les applications de l'autre | Un sous-traitant qui accède à ton outil de tickets avec ses propres comptes |
| Jeton, assertion | La preuve signée remise par le fournisseur d'identité | Un ID token JWT en OIDC, une assertion XML en SAML |
OAuth 2.0 : déléguer une autorisation, pas prouver une identité
OAuth 2.0 (RFC 6749) est un protocole d'autorisation déléguée. Il répond à cette question : comment permettre à une application d'accéder à des données d'un utilisateur, chez un autre service, sans lui donner le mot de passe de ce service ? Exemple : une application de planification veut lire l'agenda professionnel de Julie. Plutôt que de demander son mot de passe, elle la redirige vers le service d'agenda, où Julie consent ; l'application reçoit un jeton d'accès limité à la lecture de l'agenda.
Quatre rôles :
- le propriétaire de la ressource : Julie ;
- le client : l'application de planification ;
- le serveur d'autorisation : celui qui authentifie Julie, recueille son consentement et délivre les jetons ;
- le serveur de ressources : l'API de l'agenda, qui accepte le jeton d'accès.
Le jeton d'accès est limité par des portées (scopes), par exemple agenda.lecture, et par une durée de vie courte.
Le flux à retenir : le code d'autorisation avec PKCE
OAuth 2.0 définit plusieurs façons d'obtenir un jeton, les flux (grants). Les recommandations de sécurité publiées par l'IETF en janvier 2025 (RFC 9700) en écartent deux : le flux implicite (le jeton revenait dans l'URL) et le flux qui transmet le mot de passe de l'utilisateur au client. Pour un utilisateur, il reste le flux du code d'autorisation, protégé par PKCE (Proof Key for Code Exchange, RFC 7636), que le serveur d'autorisation doit prendre en charge pour tous les types de clients.
Le code passe par le navigateur ; les jetons, jamais (pour une application avec une partie serveur, le cas du schéma). Les étapes 1 et 3 sont des redirections : le navigateur porte la demande à l'IdP, puis rapporte le code à l'application. Les étapes 4 et 5 se font sur un canal direct entre l'application et l'IdP : un code intercepté ne suffit pas, il faut aussi le code_verifier, que seule l'application connaît.
Les paramètres de la première redirection ont chacun un rôle de sécurité :
| Paramètre | Rôle |
|---|---|
client_id | Identifie l'application auprès du fournisseur d'identité |
redirect_uri | L'adresse exacte où renvoyer le code : le fournisseur refuse toute adresse non enregistrée |
response_type=code | On demande un code d'autorisation, pas un jeton directement |
scope=openid profile email | openid déclenche OpenID Connect ; profile et email demandent ces informations |
state | Valeur aléatoire que l'application vérifie au retour : protège contre le CSRF sur le retour |
nonce | Valeur aléatoire recopiée dans l'ID token : empêche de rejouer un ancien jeton |
code_challenge, code_challenge_method=S256 | L'empreinte SHA-256 du code_verifier : un code intercepté est inutilisable sans le secret |
Le PKCE se calcule ainsi : code_challenge = BASE64URL(SHA256(code_verifier)). Avec l'exemple de la RFC 7636, le vérificateur dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk donne le défi E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM. Seule l'application qui a généré le vérificateur peut échanger le code.
Pour les échanges entre machines, sans utilisateur (un script de synchronisation qui appelle une API), on utilise le flux des identifiants client (client credentials) : le service s'authentifie avec son propre identifiant et un secret ou un certificat.
OpenID Connect et l'ID token
OpenID Connect (OIDC) ajoute à OAuth 2.0 l'ID token, un JWT signé par le fournisseur d'identité qui décrit l'authentification :
{
"iss": "https://sso.sorbier.example/realms/sorbier",
"sub": "f3a1c9e2-5b7d-4c1e-9a0b-2d6e8f4a7c31",
"aud": "outil-tickets",
"exp": 1793607300,
"iat": 1793607000,
"nonce": "n-0S6_WzA2Mj",
"auth_time": 1793606990,
"amr": ["pwd", "otp"],
"email": "chloe.lambert@sorbier.example",
"name": "Chloé Lambert"
}
Avant de croire l'ID token, l'application vérifie :
- la signature, avec la clé publique du fournisseur (publiée dans un document JWKS) ;
- l'émetteur
iss: c'est bien notre fournisseur d'identité ; - l'audience
aud: le jeton a été émis pour cette application, pas pour une autre ; - l'expiration
exp; - le
nonce, égal à celui qu'elle a envoyé.
Le fournisseur publie toute sa configuration (adresses des points d'accès, clés, algorithmes) à une adresse normalisée, /.well-known/openid-configuration : une bibliothèque OIDC s'y connecte et récupère tout automatiquement.
SAML 2.0
SAML 2.0 (Security Assertion Markup Language, 2005) fait la même chose qu'OIDC avec des assertions XML signées, transmises par le navigateur au moyen de redirections et de formulaires. Il reste très répandu pour les applications d'entreprise (logiciels RH, outils en ligne) et dans l'enseignement supérieur.
| Critère | SAML 2.0 | OpenID Connect |
|---|---|---|
| Format de la preuve | Assertion XML signée | ID token JWT signé |
| Année | 2005 | 2014 |
| Usage typique | Applications web d'entreprise, fédérations historiques | Applications web et mobiles récentes, API |
| Applications mobiles et API | Mal adapté | Conçu pour |
| Délégation d'accès à une API | Non | Oui, grâce à OAuth 2.0 |
Dans un domaine Active Directory, les postes Windows bénéficient d'une autre forme d'authentification unique : le ticket Kerberos obtenu à l'ouverture de session donne accès aux partages, aux imprimantes et à l'intranet sans nouvelle saisie (chapitre 7). Les fournisseurs d'identité web comme Keycloak savent d'ailleurs s'appuyer sur l'annuaire et sur Kerberos.
Côté SISR : mettre en place un fournisseur d'identité
Antoine Mercier veut que les salariés de Sorbier Logistique accèdent à l'outil de tickets, à l'intranet et au wiki avec leur compte du domaine. Sa démarche :
- Inventorier l'existant : quelles applications, quels comptes, quels rôles dans chacune. C'était tout le dossier A du sujet de 2024, qui faisait écrire une vue SQL rassemblant les comptes de plusieurs bases (une
UNION: voir les vues SQL) et créer un compte de base de données aux droits strictement nécessaires pour le programme d'inventaire. - Installer le fournisseur d'identité, par exemple Keycloak (libre) dans un conteneur, en HTTPS avec un certificat valide, derrière le pare-feu.
- Le relier à l'annuaire : Keycloak lit les comptes et les groupes de l'Active Directory en LDAPS, sans copier les mots de passe.
- Déclarer chaque application comme client, avec son adresse de retour exacte, et associer les groupes de l'annuaire aux rôles de l'application.
- Activer la MFA pour tous, et la rendre obligatoire pour les rôles sensibles.
- Prévoir la disponibilité : deux instances, une sauvegarde de la configuration, une procédure si le fournisseur est indisponible.
- Centraliser les journaux de connexion et alerter sur les anomalies.
Côté SLAM : intégrer OpenID Connect dans une application
Le développeur n'écrit pas le protocole : il utilise une bibliothèque certifiée (il en existe pour Node.js, PHP, Java, C# et Python) et configure trois choses : l'adresse du fournisseur, l'identifiant et le secret du client, l'adresse de retour. Le parcours dans l'application :
- la route
/connexiongénèrestate,nonceetcode_verifier, les garde dans la session et redirige vers le fournisseur ; - la route de retour
/auth/callbackvérifie questatecorrespond, échange le code contre les jetons, puis fait vérifier l'ID token par la bibliothèque (signature,iss,aud,exp,nonce) ; - l'application retrouve ou crée l'utilisateur local à partir de
sub(stable et unique, contrairement à l'adresse mail qui peut changer), puis ouvre sa propre session, avec les réglages du chapitre 5 ; - à la déconnexion, elle ferme sa session et peut rediriger vers la déconnexion du fournisseur, pour fermer aussi la session SSO.
Les erreurs d'intégration classiques
| Erreur | Conséquence | Correction |
|---|---|---|
redirect_uri acceptant des jokers (https://*.sorbier.example/*) | Un attaquant fait envoyer le code vers une page qu'il contrôle | Enregistrer les adresses exactes |
state absent ou non vérifié | Un attaquant connecte la victime à son compte (CSRF de connexion) | Générer, stocker et comparer state |
| Flux implicite, jeton dans l'URL | Le jeton fuit dans l'historique et les journaux | Code d'autorisation avec PKCE |
ID token accepté sans vérifier aud | Un jeton émis pour une autre application est accepté | Faire vérifier aud par la bibliothèque |
| Secret client dans le code JavaScript d'une page | Tout le monde le lit | Une application dans le navigateur est un client public : PKCE, sans secret |
Comment l'E7 l'interroge
- SLAM (sujet 2024) : inventorier les comptes de plusieurs applications avant un SSO ; créer un compte SQL aux droits minimaux ; identifier les conséquences d'une API dont aucune route ne vérifie l'utilisateur appelant ; expliquer pourquoi un jeton est refusé après expiration ; compléter le rafraîchissement d'un jeton ; analyser l'effet du SSO sur un scénario de risque. On peut aussi te demander de distinguer ID token et jeton d'accès, ou de repérer une
redirect_uritrop permissive. - SISR : proposer une solution d'authentification unique pour plusieurs applications internes ; relier le fournisseur d'identité à l'annuaire en LDAPS ; traiter la disponibilité du fournisseur d'identité (redondance, sauvegarde).
- Tronc commun : expliquer l'intérêt et le risque du SSO ; distinguer authentification (OIDC) et autorisation déléguée (OAuth 2.0).
Exercices
Exercice 1 sur 4 OAuth 2.0 ou OpenID Connect ? Réussi À revoir
Pour chaque besoin, indique le protocole adapté.
- L'intranet de Sorbier Logistique veut savoir quel salarié se connecte, sans gérer de mots de passe.
- Un outil de reporting doit lire chaque nuit les tickets de l'API du helpdesk, sans utilisateur présent.
- Une application de covoiturage veut ajouter des trajets dans l'agenda professionnel d'un salarié, avec son accord.
Voir la réponseMasquer la réponse de l'exercice 1
- OpenID Connect : il faut prouver l'identité de l'utilisateur ; l'ID token la fournit.
- OAuth 2.0, flux des identifiants client : un service s'authentifie lui-même pour obtenir un jeton d'accès limité à la lecture des tickets.
- OAuth 2.0, flux du code d'autorisation avec PKCE : le salarié consent, l'application reçoit un jeton d'accès limité à l'écriture dans l'agenda, sans jamais connaître son mot de passe.
Tu avais trouvé ?
Exercice 2 sur 4 Vérifier un ID token Réussi À revoir
L'outil de tickets (client_id : outil-tickets) reçoit un ID token valide, bien signé par https://sso.sorbier.example/realms/sorbier, non expiré, dont l'audience est aud: "wiki". Doit-il l'accepter ? Pourquoi ce contrôle existe-t-il ?
Voir la réponseMasquer la réponse de l'exercice 2
Non. Le jeton a été émis pour le wiki, pas pour l'outil de tickets. Sans ce contrôle, toute application du même fournisseur (ou un attaquant qui aurait compromis le wiki et récupéré les jetons de ses utilisateurs) pourrait présenter ses jetons à l'outil de tickets et s'y connecter sous l'identité des utilisateurs. L'audience garantit qu'un jeton ne sert que là où il devait servir.
Tu avais trouvé ?
Exercice 3 sur 4 Le SSO et le scénario de risque Réussi À revoir
Avant le SSO, le scénario « vol du mot de passe d'un salarié » avait été évalué à une vraisemblance de 3 sur 4 et une gravité de 2 sur 4 : chaque application avait son propre mot de passe et peu de données sensibles. Après le SSO, le même compte donne accès à la paie et aux dossiers RH.
- Comment évolue le niveau de risque ?
- Propose deux mesures pour le réduire.
Voir la réponseMasquer la réponse de l'exercice 3
- La gravité augmente : le même vol ouvre désormais des applications qui contiennent des données personnelles sensibles (paie, RH). Elle passe au moins à 3, voire 4 sur 4. La vraisemblance ne baisse pas d'elle-même (un seul mot de passe, mieux protégé, peut même la réduire un peu). Le risque global augmente.
- Imposer une authentification multifacteur au fournisseur d'identité, résistante à l'hameçonnage pour les rôles sensibles, ce qui fait baisser la vraisemblance ; limiter la durée des sessions SSO et demander une réauthentification pour accéder à la paie ; surveiller les connexions inhabituelles (pays, horaires) avec des alertes.
Tu avais trouvé ?
Exercice 4 sur 4 Les paramètres de la redirection Réussi À revoir
Voici l'adresse vers laquelle une application redirige le navigateur :
https://sso.sorbier.example/realms/sorbier/protocol/openid-connect/auth?response_type=token&client_id=intranet&redirect_uri=https://intranet.sorbier.example/retour&scope=profile
Relève trois problèmes.
Voir la réponseMasquer la réponse de l'exercice 4
response_type=token: c'est le flux implicite, déconseillé par la RFC 9700 (le jeton revient dans l'URL). Il fautresponse_type=code.- Pas de
state, denonceni decode_challenge: ni protection CSRF, ni protection contre le rejeu, ni PKCE. scope=profilesansopenid: OpenID Connect n'est pas déclenché, l'application ne recevra pas d'ID token, donc pas de preuve d'identité.
Tu avais trouvé ?