[{"data":1,"prerenderedAt":480},["ShallowReactive",2],{"deck:auth":3},{"deck":4,"reason":478,"status":479},{"id":5,"stem":6,"matiere":7,"name":8,"punchline":9,"deckStatus":10,"customMessages":11,"sources":21,"cards":31},"auth","decks/auth","informatique","Authentification","Qui es-tu, et qu'as-tu le droit de faire","publié",{"low":12,"medium":15,"high":18},[13,14],"Authn puis authz : dans cet ordre","Un JWT se lit, il ne se cache pas",[16,17],"Les flows OAuth se dessinent","Access token à l'API, ID token au client",[19,20],"PKCE, nonce, aud : plus une faille dans le flow","SSO, SAML, OIDC : tu sais qui fait confiance à qui",[22,25,28],{"title":23,"url":24},"RFC 6749 — The OAuth 2.0 Authorization Framework (IETF)","https://datatracker.ietf.org/doc/html/rfc6749",{"title":26,"url":27},"RFC 7519 — JSON Web Token (IETF)","https://datatracker.ietf.org/doc/html/rfc7519",{"title":29,"url":30},"OpenID Connect Core 1.0","https://openid.net/specs/openid-connect-core-1_0.html",[32,41,49,56,69,78,85,93,104,112,122,132,140,148,155,167,174,182,189,201,211,218,225,232,239,247,264,274,285,292,299,307,317,324,331,338,349,356,363,371,378,390,397,405,413,425,436,447,454,464,471],{"id":33,"tags":34,"question":37,"quick_answer":38,"details":39,"difficulty":40},"auth-001",[7,5,35,36],"securite","concepts","Qu'est-ce que l'**authentification** ?","Vérifier que quelqu'un est bien qui il prétend être","C'est la question « **qui es-tu ?** » : mot de passe, code SMS, empreinte, clé physique. Le résultat est une identité vérifiée (un `sub`, un identifiant utilisateur).\n\nAbréviation courante : **authn**.",2,{"id":42,"tags":43,"question":44,"quick_answer":45,"details":46,"dependsOn":47,"difficulty":48},"auth-002",[7,5,35,36],"Qu'est-ce que l'**autorisation** ?","Décider ce qu'une identité déjà vérifiée a le droit de faire","C'est la question « **as-tu le droit ?** » : lire ce document, supprimer ce compte, accéder à l'admin. Elle vient toujours **après** l'authentification et s'exprime en rôles (RBAC), attributs (ABAC) ou permissions.\n\nAbréviation : **authz**. Une erreur 401 = pas authentifié ; 403 = authentifié mais pas autorisé.",[33],3,{"id":50,"tags":51,"question":52,"quick_answer":53,"details":54,"dependsOn":55,"difficulty":48},"auth-003",[7,5,35,36],"Quels sont les trois **facteurs** d'authentification ?","Ce que je sais, ce que je possède, ce que je suis","- **Savoir** : mot de passe, code PIN\n- **Posséder** : téléphone (code TOTP, SMS), clé USB FIDO, carte à puce\n- **Être** : empreinte digitale, visage\n\nLa **MFA** (authentification multifacteur) combine au moins deux facteurs **différents**. Deux mots de passe ne font pas de la MFA.",[33],{"id":57,"tags":58,"question":60,"quick_answer":61,"details":62,"dependsOn":63,"difficulty":64,"sources":65},"auth-004",[7,5,35,59],"mots-de-passe","Comment stocker un **mot de passe** en base de données ?","Jamais en clair ni chiffré : haché avec un algorithme lent et salé (bcrypt, scrypt, Argon2)","Un hachage est à sens unique : on ne retrouve pas le mot de passe, on vérifie seulement qu'une saisie donne le même hash. Le **sel** (valeur aléatoire par utilisateur) empêche les tables précalculées. La **lenteur** volontaire (facteur de coût) rend la force brute coûteuse.\n\nMD5 et SHA-256 seuls sont inadaptés : trop rapides, des milliards d'essais par seconde sur un GPU. Recommandation OWASP actuelle : **Argon2id**.",[33],5,[66],{"title":67,"url":68},"OWASP — Password Storage Cheat Sheet","https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html",{"id":70,"tags":71,"question":73,"quick_answer":74,"details":75,"dependsOn":76,"difficulty":77},"auth-005",[7,5,72],"sessions","Comment fonctionne une **session** classique côté serveur ?","Le serveur stocke l'état de connexion et donne au navigateur un identifiant de session dans un cookie","Après login, le serveur crée une entrée (en mémoire, Redis, base) et renvoie `Set-Cookie: session=abc123`. À chaque requête, le navigateur renvoie le cookie, le serveur retrouve l'utilisateur.\n\nAvantage : révocation immédiate (on supprime l'entrée). Inconvénient : l'état est côté serveur, à partager entre instances.",[33],4,{"id":79,"tags":80,"question":81,"quick_answer":82,"details":83,"dependsOn":84,"difficulty":77},"auth-006",[7,5,72,35],"Que fait l'attribut **HttpOnly** sur un cookie ?","Interdit à JavaScript de lire le cookie : une faille XSS ne peut plus le voler","`document.cookie` ne le voit pas ; seul le navigateur l'envoie avec les requêtes. Les deux autres attributs essentiels : **Secure** (envoyé uniquement en HTTPS) et **SameSite** (`Lax` ou `Strict`, limite l'envoi depuis un autre site, contre le CSRF).\n\nUn cookie de session se configure `HttpOnly; Secure; SameSite=Lax` au minimum.",[70],{"id":86,"tags":87,"question":89,"quick_answer":90,"details":91,"dependsOn":92,"difficulty":64},"auth-007",[7,5,35,88],"attaques","Qu'est-ce qu'une attaque **CSRF** ?","Un site malveillant fait émettre par ton navigateur une requête vers un site où tu es connecté·e","Cross-Site Request Forgery. Tu es connecté·e à ta banque ; une page piégée contient un formulaire auto-soumis vers `banque.fr/virement`. Le navigateur joint le cookie de session, la banque croit que c'est toi.\n\nDéfenses : cookie `SameSite`, jeton anti-CSRF dans le formulaire, vérification de l'en-tête `Origin`. Un token dans un header `Authorization` (pas un cookie) n'est pas envoyé automatiquement : pas de CSRF.",[70],{"id":94,"tags":95,"question":97,"quick_answer":98,"details":99,"dependsOn":100,"difficulty":77,"sources":101},"auth-008",[7,5,96],"jwt","Qu'est-ce qu'un **JWT** ?","Un jeton en trois parties encodées base64url, header.payload.signature, dont la signature garantit l'intégrité","JSON Web Token (RFC 7519), prononcé « jot ». Le **header** dit l'algorithme (`alg`) et le type ; le **payload** contient les claims (`sub`, `exp`…) ; la **signature** est calculée sur les deux premiers.\n\nLe serveur vérifie la signature sans rien chercher en base : le jeton se suffit à lui-même (**stateless**).",[33],[102],{"title":103,"url":27},"RFC 7519 — JSON Web Token",{"id":105,"tags":106,"question":108,"quick_answer":109,"details":110,"dependsOn":111,"difficulty":77},"auth-009",[7,5,96,107],"pieges","Le contenu d'un JWT est-il **confidentiel** ?","Non : le payload est seulement encodé en base64, n'importe qui peut le lire","Coller un JWT sur jwt.io suffit à voir ses claims. La signature garantit que personne ne l'a **modifié**, pas que personne ne le **lit**.\n\nDonc : jamais de mot de passe, de données personnelles sensibles ou de secret dans un JWT. Si la confidentialité est requise, il existe le **JWE** (JWT chiffré), rarement utilisé.",[94],{"id":113,"tags":114,"question":115,"quick_answer":116,"details":117,"dependsOn":118,"difficulty":48,"sources":119},"auth-010",[7,5,96],"Que contient le claim **sub** d'un JWT ?","Le sujet : l'identifiant de l'utilisateur (ou de la machine) que le jeton représente","Un identifiant stable et opaque (UUID), pas un e-mail qui peut changer. C'est la clé pour retrouver l'utilisateur côté serveur.\n\nAutres claims standard : `iss` (émetteur), `aud` (destinataire), `exp` (expiration), `iat` (émis à), `nbf` (pas avant), `jti` (identifiant unique du jeton).",[94],[120],{"title":121,"url":27},"RFC 7519 — Registered claim names",{"id":123,"tags":124,"question":125,"quick_answer":126,"details":127,"dependsOn":128,"difficulty":48,"sources":129},"auth-011",[7,5,96],"Que contient le claim **exp** d'un JWT ?","La date d'expiration, en secondes depuis le 1er janvier 1970 (epoch Unix)","`\"exp\": 1760400000`. Tout vérificateur doit refuser un jeton expiré. Une petite tolérance (clock skew, quelques secondes à quelques minutes selon la RFC) est admise pour les horloges désynchronisées.\n\nUn JWT **sans `exp`** est valable pour toujours : une bibliothèque sérieuse le refuse ou prévient.",[113],[130],{"title":131,"url":27},"RFC 7519 — exp claim",{"id":133,"tags":134,"question":135,"quick_answer":136,"details":137,"dependsOn":138,"difficulty":139},"auth-012",[7,5,96,107],"Pourquoi vérifier le claim **aud** (audience) d'un JWT ?","Pour refuser un jeton valide émis pour un autre service","Un même fournisseur d'identité signe des jetons pour l'API A et l'API B. Sans vérification d'audience, un jeton volé destiné à A est accepté par B : la signature est bonne, l'émetteur est bon.\n\nChaque service vérifie que `aud` contient son propre identifiant. Même logique pour `iss` : n'accepter que les émetteurs attendus.",[113],6,{"id":141,"tags":142,"question":144,"quick_answer":145,"details":146,"dependsOn":147,"difficulty":64},"auth-013",[7,5,96,143],"cryptographie","Comment fonctionne la signature **HS256** d'un JWT ?","HMAC-SHA256 avec un secret partagé : qui vérifie peut aussi signer","Symétrique. Émetteur et vérificateur ont le même secret. Simple et rapide, adapté quand c'est le **même service** qui émet et vérifie.\n\nProblème : chaque service qui doit vérifier le jeton reçoit le secret, donc peut forger des jetons. Un secret court ou devinable se casse par force brute hors ligne.",[94],{"id":149,"tags":150,"question":151,"quick_answer":152,"details":153,"dependsOn":154,"difficulty":64},"auth-014",[7,5,96,143],"Comment fonctionne la signature **RS256** d'un JWT ?","RSA : la clé privée signe, la clé publique vérifie","Asymétrique. Seul le fournisseur d'identité possède la clé privée ; il publie la clé publique (via JWKS). N'importe quelle API peut vérifier sans pouvoir forger.\n\nC'est le choix par défaut dès qu'un émetteur sert plusieurs consommateurs (OIDC). **ES256** (courbes elliptiques) fait la même chose avec des clés et signatures plus courtes.",[141],{"id":156,"tags":157,"question":158,"quick_answer":159,"details":160,"dependsOn":161,"difficulty":162,"sources":163},"auth-015",[7,5,96,88],"Quelle est l'attaque **alg: none** sur les JWT ?","Forger un jeton dont le header déclare alg none, sans signature, qu'une bibliothèque naïve accepte","La spec autorise `\"alg\": \"none\"` pour les jetons non sécurisés. Certaines bibliothèques historiques faisaient confiance au header et validaient le jeton sans signature.\n\nRègle : le serveur **impose** l'algorithme attendu (`algorithms: ['RS256']`) et ne lit jamais `alg` depuis le jeton pour décider. Attaque cousine, même cause (faire confiance au `alg` du header) : la confusion de clé, où un jeton `HS256` est signé avec la clé **publique** RSA comme secret HMAC.",[141],7,[164],{"title":165,"url":166},"RFC 8725 — JWT Best Current Practices","https://datatracker.ietf.org/doc/html/rfc8725",{"id":168,"tags":169,"question":170,"quick_answer":171,"details":172,"dependsOn":173,"difficulty":139},"auth-016",[7,5,96,107],"Comment **révoquer** un JWT avant son expiration ?","On ne peut pas vraiment : d'où des jetons courts (minutes) et une blocklist ou un refresh token","Le jeton est autonome : le serveur n'interroge rien pour le valider, donc rien ne peut le « supprimer ». Options :\n- **Durée courte** (5 à 15 min) : la fenêtre de risque est bornée\n- **Blocklist** des `jti` révoqués, consultée à chaque requête (on perd le stateless)\n- Révoquer le **refresh token** : l'utilisateur ne pourra plus obtenir de nouvel access token\n\nUne session serveur classique, elle, se révoque instantanément.",[123,70],{"id":175,"tags":176,"question":178,"quick_answer":179,"details":180,"dependsOn":181,"difficulty":64},"auth-017",[7,5,96,177],"oauth","Qu'est-ce qu'un **refresh token** ?","Un jeton longue durée qui sert uniquement à obtenir un nouvel access token, sans refaire le login","L'access token circule à chaque requête API, donc il expire vite (minutes). Le refresh token ne circule qu'entre le client et l'authorization server, vit des jours ou des semaines, et peut être révoqué côté serveur : c'est lui qu'on coupe pour déconnecter quelqu'un.\n\nIl n'est jamais envoyé à une API.",[168],{"id":183,"tags":184,"question":185,"quick_answer":186,"details":187,"dependsOn":188,"difficulty":139},"auth-018",[7,5,96,35],"Où stocker un token côté navigateur : **localStorage** ou cookie ?","Cookie HttpOnly de préférence : localStorage est lisible par tout script, donc volable par XSS","`localStorage` est pratique (on lit le token et on le met dans `Authorization`), mais une seule injection JavaScript (dépendance compromise, XSS) l'exfiltre.\n\nLe cookie `HttpOnly` est invisible au JS, mais est envoyé automatiquement : il faut alors gérer le CSRF (`SameSite`). Compromis courant pour les SPA : un backend « BFF » qui garde les tokens et parle au front par cookie de session.",[79,94],{"id":190,"tags":191,"question":193,"quick_answer":194,"details":195,"dependsOn":196,"difficulty":48,"sources":197},"auth-019",[7,5,192],"http","Comment un client envoie-t-il un token à une API HTTP ?","Dans l'en-tête Authorization: Bearer \u003Ctoken>","« Bearer » = porteur : quiconque **détient** le jeton est considéré comme autorisé, sans autre preuve. D'où l'importance de HTTPS et de durées courtes.\n\nL'API répond `401` avec `WWW-Authenticate: Bearer` si le jeton manque ou est invalide. Défini par la RFC 6750.",[94],[198],{"title":199,"url":200},"RFC 6750 — Bearer Token Usage","https://datatracker.ietf.org/doc/html/rfc6750",{"id":202,"tags":203,"question":204,"quick_answer":205,"details":206,"dependsOn":207,"difficulty":64,"sources":208},"auth-020",[7,5,177],"Qu'est-ce qu'**OAuth 2.0** ?","Un cadre d'autorisation déléguée : une app obtient un accès limité au nom d'un utilisateur","« Laisser l'app X lire mon agenda Google sans lui donner mon mot de passe Google. » L'utilisateur consent chez le fournisseur, l'application reçoit un access token aux droits restreints (scopes).\n\nOAuth 2.0 (RFC 6749) ne dit **rien** sur l'identité de l'utilisateur : c'est de l'**autorisation**. L'authentification est ajoutée par OpenID Connect.",[42],[209],{"title":210,"url":24},"RFC 6749 — OAuth 2.0 Authorization Framework",{"id":212,"tags":213,"question":214,"quick_answer":215,"details":216,"dependsOn":217,"difficulty":77},"auth-021",[7,5,177],"Dans OAuth 2.0, qu'est-ce que l'**authorization server** ?","Le serveur qui authentifie l'utilisateur, recueille son consentement et émet les tokens","Keycloak, Auth0, Google, Microsoft Entra, Cognito… Il expose au minimum deux endpoints, typiquement `/authorize` (où le navigateur est redirigé) et `/token` (où le client échange un code contre des tokens) ; leurs URI exactes sont publiées par le document de découverte.\n\nLe **resource owner**, c'est l'utilisateur qui consent.",[202],{"id":219,"tags":220,"question":221,"quick_answer":222,"details":223,"dependsOn":224,"difficulty":77},"auth-022",[7,5,177],"Dans OAuth 2.0, qu'est-ce que le **resource server** ?","L'API qui héberge les données protégées et accepte les access tokens","Il ne connaît pas le mot de passe de l'utilisateur et ne l'authentifie pas lui-même : il **valide le token** (signature, expiration, audience, scopes) émis par l'authorization server.\n\nSouvent le même organisme (l'API Google valide les tokens Google), parfois pas (une API maison valide les tokens d'un Keycloak).",[212],{"id":226,"tags":227,"question":228,"quick_answer":229,"details":230,"dependsOn":231,"difficulty":77},"auth-023",[7,5,177],"Dans OAuth 2.0, qu'est-ce qu'un **client** ?","L'application qui demande l'accès, identifiée par un client_id","Un client **confidentiel** (backend) peut garder un `client_secret`. Un client **public** (SPA, app mobile, CLI) ne peut rien cacher : son code est entre les mains de l'utilisateur. Cette distinction décide du flow et impose PKCE aux clients publics.\n\nLe client est enregistré chez l'authorization server avec ses `redirect_uri` autorisées.",[212],{"id":233,"tags":234,"question":235,"quick_answer":236,"details":237,"dependsOn":238,"difficulty":48},"auth-024",[7,5,177],"Qu'est-ce qu'un **scope** OAuth ?","Une permission demandée par le client et affichée à l'utilisateur au consentement","`read:calendar`, `repo`, `email`. Le token émis porte les scopes accordés ; le resource server vérifie que le scope requis est présent.\n\nPrincipe du moindre privilège : demander le minimum. Une app qui réclame `repo` complet pour lire un README fait fuir les utilisateurs attentifs.",[202],{"id":240,"tags":241,"question":243,"answer":244,"details":245,"dependsOn":246,"difficulty":162},"auth-025",[7,5,177,242],"flows","Étapes du flow **Authorization Code** ?","1. Le client redirige le navigateur vers `/authorize` (client_id, redirect_uri, scope, state)\n2. L'utilisateur s'authentifie et consent chez l'authorization server\n3. Redirection vers `redirect_uri` avec un **code** à usage unique\n4. Le client échange ce code contre des tokens sur `/token`, par un appel **serveur à serveur**\n5. Le client appelle l'API avec l'access token","L'intérêt du détour par le code : les tokens ne transitent jamais par le navigateur ni par l'historique d'URL. Le code seul ne sert à rien sans le secret du client (ou le code_verifier PKCE).\n\nC'est le flow recommandé pour toutes les applications avec un utilisateur.",[212,226],{"id":248,"tags":249,"question":250,"quick_answer":251,"details":252,"dependsOn":253,"difficulty":139,"sources":254},"auth-026",[7,5,177,242],"Qu'est-ce que **PKCE** ?","Prouver que celui qui échange le code est celui qui l'a demandé","Proof Key for Code Exchange, prononcé « pixy » (RFC 7636). Mécanisme : un `code_verifier` aléatoire côté client, son hash en `code_challenge` envoyé à l'autorisation. Le client génère un secret aléatoire (`code_verifier`), envoie son hash SHA-256 (`code_challenge`) à `/authorize`, puis le verifier en clair à `/token`. Un code intercepté est inutilisable sans le verifier.\n\nOAuth 2.0 + Security BCP (RFC 9700) : obligatoire pour les clients publics (SPA, mobile), recommandé pour les confidentiels. OAuth 2.1 : obligatoire pour tous par défaut. Authorization Code + PKCE remplace l'ancien flow implicite.",[240],[255,258,261],{"title":256,"url":257},"RFC 7636 — PKCE","https://datatracker.ietf.org/doc/html/rfc7636",{"title":259,"url":260},"RFC 9700 — OAuth 2.0 Security BCP","https://datatracker.ietf.org/doc/html/rfc9700",{"title":262,"url":263},"OAuth 2.1 (draft IETF)","https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1",{"id":265,"tags":266,"question":267,"quick_answer":268,"details":269,"dependsOn":270,"difficulty":64,"sources":271},"auth-027",[7,5,177,242],"Pourquoi le flow **Implicit** est-il déprécié ?","Le token arrive dans l'URL du navigateur (fragment), exposé à l'historique, aux scripts et aux extensions","Conçu pour les SPA avant que les navigateurs n'autorisent les appels cross-origin. Pas de code intermédiaire, pas de refresh token, token dans `#access_token=…`.\n\nRemplacé par Authorization Code + PKCE. OAuth 2.1 le retire de la spécification.",[248],[272,273],{"title":259,"url":260},{"title":262,"url":263},{"id":275,"tags":276,"question":277,"quick_answer":278,"details":279,"dependsOn":280,"difficulty":77,"sources":281},"auth-028",[7,5,177,242],"Quel flow OAuth utiliser pour une communication **machine à machine**, sans utilisateur ?","Client Credentials : le client s'authentifie avec son client_id et client_secret et reçoit un token","Un cron, un microservice qui appelle une API interne. Pas de navigateur, pas de consentement, pas de refresh token (on redemande un token quand il expire).\n\nLe token représente l'**application**, pas une personne : le `sub` identifie l'application (en général le client_id).",[226],[282],{"title":283,"url":284},"RFC 9068 — JWT profile for OAuth 2.0 access tokens","https://datatracker.ietf.org/doc/html/rfc9068",{"id":286,"tags":287,"question":288,"quick_answer":289,"details":290,"dependsOn":291,"difficulty":139},"auth-029",[7,5,177,35],"Pourquoi l'authorization server exige-t-il que la **redirect_uri** soit enregistrée à l'avance ?","Sinon un attaquant fait envoyer le code (ou le token) vers son propre site","Le client malveillant lance un flow avec le `client_id` d'une app légitime et `redirect_uri=https://evil.com`. L'utilisateur consent (il voit le nom de l'app légitime), le code part chez l'attaquant.\n\nLa comparaison doit être **exacte** (pas de préfixe, pas de joker) : `https://app.com/cb` ≠ `https://app.com/cb/../evil`.",[240],{"id":293,"tags":294,"question":295,"quick_answer":296,"details":297,"dependsOn":298,"difficulty":139},"auth-030",[7,5,177,35],"À quoi sert le paramètre **state** dans un flow OAuth ?","À lier la réponse à la requête initiale : protection CSRF du flow","Le client génère une valeur aléatoire, la stocke en session, l'envoie dans `/authorize`. L'authorization server la renvoie telle quelle avec le code. Si elle ne correspond pas, on rejette.\n\nSans `state`, un attaquant peut faire aboutir dans **ta** session un code obtenu avec **son** compte (login CSRF), et tu travailles ensuite sur ses données sans le savoir.",[240,86],{"id":300,"tags":301,"question":303,"quick_answer":304,"details":305,"dependsOn":306,"difficulty":64},"auth-031",[7,5,302],"oidc","Qu'est-ce qu'**OpenID Connect** (OIDC) ?","Une couche d'identité au-dessus d'OAuth 2.0 : elle ajoute l'authentification et l'ID token","OAuth dit « cette app peut accéder à ça ». OIDC ajoute « et voici **qui** est l'utilisateur connecté », de façon standardisée : ID token (un JWT), endpoint `/userinfo`, document de découverte, scopes `openid profile email`.\n\n« Se connecter avec Google / Microsoft / GitHub » = OIDC en pratique.",[202,94],{"id":308,"tags":309,"question":310,"quick_answer":311,"details":312,"dependsOn":313,"difficulty":64,"sources":314},"auth-032",[7,5,302],"Qu'est-ce que l'**ID token** ?","Un JWT destiné au client, qui atteste l'identité de l'utilisateur authentifié","Claims : `sub` (identifiant), `iss`, `aud` (= le client_id), `exp`, `iat`, `auth_time`, `nonce`, et souvent `email`, `name`.\n\nIl est fait pour être **lu par le client** : il sert à ouvrir la session locale de l'application.",[300],[315],{"title":316,"url":30},"OpenID Connect Core 1.0 — ID Token",{"id":318,"tags":319,"question":320,"quick_answer":321,"details":322,"dependsOn":323,"difficulty":162},"auth-033",[7,5,302,107],"Peut-on envoyer l'**ID token** à une API comme preuve d'autorisation ?","Non : son audience est le client, pas l'API, et il ne porte pas de scopes","Une API qui accepte un ID token viole la vérification d'`aud` et confond authentification et autorisation. L'ID token dit « cette personne s'est connectée à l'app X » ; il ne dit pas ce qu'elle peut faire sur l'API Y.\n\nLe bon jeton pour l'API est l'**access token**, émis avec une audience et des scopes pour cette API.",[308,133],{"id":325,"tags":326,"question":327,"quick_answer":328,"details":329,"dependsOn":330,"difficulty":40},"auth-034",[7,5,302],"Quel scope est **obligatoire** pour qu'une requête OAuth devienne une requête OIDC ?","openid","Sans `openid`, l'authorization server fait du OAuth pur et ne renvoie pas d'ID token. Les scopes standard qui l'accompagnent : `profile` (nom, photo…), `email`, `address`, `phone`, `offline_access` (refresh token).",[300,233],{"id":332,"tags":333,"question":334,"quick_answer":335,"details":336,"dependsOn":337,"difficulty":48},"auth-035",[7,5,302],"À quoi sert l'endpoint **/userinfo** ?","À récupérer les informations de profil de l'utilisateur avec l'access token","`GET /userinfo` avec `Authorization: Bearer \u003Caccess_token>` renvoie un JSON (`sub`, `email`, `name`…) selon les scopes accordés. Utile quand on ne veut pas gonfler l'ID token ou quand les infos peuvent changer.\n\nLe `sub` renvoyé doit correspondre à celui de l'ID token.",[308],{"id":339,"tags":340,"question":341,"quick_answer":342,"details":343,"dependsOn":344,"difficulty":77,"sources":345},"auth-036",[7,5,302],"Qu'est-ce que le **document de découverte** OIDC ?","Le JSON à /.well-known/openid-configuration qui liste les endpoints, algorithmes et clés du fournisseur","`https://accounts.google.com/.well-known/openid-configuration` renvoie `authorization_endpoint`, `token_endpoint`, `userinfo_endpoint`, `jwks_uri`, `issuer`, les scopes et algorithmes supportés.\n\nUne bibliothèque cliente n'a besoin que de l'URL de l'issuer : elle se configure toute seule à partir de là.",[300],[346],{"title":347,"url":348},"OpenID Connect Discovery 1.0","https://openid.net/specs/openid-connect-discovery-1_0.html",{"id":350,"tags":351,"question":352,"quick_answer":353,"details":354,"dependsOn":355,"difficulty":64},"auth-037",[7,5,302,96,143],"Qu'est-ce qu'un **JWKS** ?","Le jeu de clés publiques du fournisseur, publié en JSON à l'URL jwks_uri, pour vérifier les signatures","JSON Web Key Set. Chaque clé a un `kid` (key id). Le header du JWT porte le `kid` utilisé : le vérificateur choisit la bonne clé dans le JWKS, la met en cache, et la rafraîchit quand un `kid` inconnu apparaît.\n\nC'est ce qui permet la **rotation des clés** sans redéployer les API.",[339,149],{"id":357,"tags":358,"question":359,"quick_answer":360,"details":361,"dependsOn":362,"difficulty":139},"auth-038",[7,5,302,35],"À quoi sert le paramètre **nonce** en OIDC ?","À lier l'ID token à la session du client : protection contre le rejeu d'un ID token","Le client envoie une valeur aléatoire dans `/authorize` ; le fournisseur la recopie dans le claim `nonce` de l'ID token ; le client vérifie qu'elle correspond à ce qu'il a envoyé.\n\n`state` protège le flow (CSRF), `nonce` protège le jeton (rejeu). Les deux ensemble en OIDC.",[308,293],{"id":364,"tags":365,"question":367,"quick_answer":368,"details":369,"dependsOn":370,"difficulty":48},"auth-039",[7,5,366],"sso","Qu'est-ce que le **SSO** (Single Sign-On) ?","Une seule authentification qui ouvre l'accès à plusieurs applications","L'utilisateur se connecte une fois chez le fournisseur d'identité (IdP) ; les applications (SP) lui font confiance et ne redemandent pas de mot de passe. Une session chez l'IdP = connecté partout.\n\nProtocoles : **SAML** (historique, entreprise) et **OIDC** (moderne, web et mobile). Le SSO réduit les mots de passe à retenir et centralise la révocation (un départ de l'entreprise = un seul compte à couper).",[33],{"id":372,"tags":373,"question":374,"quick_answer":375,"details":376,"dependsOn":377,"difficulty":48},"auth-040",[7,5,366],"Qu'est-ce qu'un **Identity Provider** (IdP) ?","Le service qui détient les comptes et authentifie les utilisateurs pour le compte des applications","Entra ID (Azure AD), Okta, Keycloak, Google Workspace, Authentik. Il gère mots de passe, MFA, groupes, et émet des assertions (SAML) ou des tokens (OIDC).\n\nEn face, le **Service Provider** (SP, terme SAML) ou **Relying Party** (RP, terme OIDC) : l'application qui délègue l'authentification à l'IdP.",[364],{"id":379,"tags":380,"question":382,"quick_answer":383,"details":384,"dependsOn":385,"difficulty":64,"sources":386},"auth-041",[7,5,366,381],"saml","Qu'est-ce que **SAML** ?","Un protocole de SSO basé sur XML : l'IdP envoie à l'application une assertion signée qui décrit l'utilisateur","Security Assertion Markup Language, version 2.0 depuis 2005. Le navigateur est redirigé vers l'IdP, puis renvoie à l'application (via un formulaire POST) une **assertion XML** signée contenant l'identité et les attributs.\n\nDominant dans les grandes entreprises et les SaaS B2B. Plus lourd qu'OIDC, inadapté au mobile et aux API, mais partout dans l'existant.",[372],[387],{"title":388,"url":389},"OASIS — SAML standard","https://www.oasis-open.org/standard/saml/",{"id":391,"tags":392,"question":393,"quick_answer":394,"details":395,"dependsOn":396,"difficulty":64},"auth-042",[7,5,366],"Qu'est-ce que la **fédération d'identité** ?","Faire confiance à l'IdP d'une autre organisation pour authentifier ses utilisateurs","L'entreprise A laisse les employés de B accéder à son outil avec leur compte B : A ne crée pas de comptes, elle fait confiance aux assertions de l'IdP de B.\n\nC'est le SSO étendu entre organisations ; techniquement SAML ou OIDC, plus un accord de confiance (échange de métadonnées, de clés). AWS IAM Identity Center ou le « login avec Google » en sont des cas.",[372],{"id":398,"tags":399,"question":401,"quick_answer":402,"details":403,"dependsOn":404,"difficulty":77},"auth-043",[7,5,400],"api","Qu'est-ce qu'une **clé d'API** ?","Un secret statique qui identifie une application appelante, sans représenter un utilisateur","`X-API-Key: abc…`. Simple à mettre en place, utile pour identifier un intégrateur, faire du quota et de la facturation.\n\nCe qu'elle ne fait pas : pas d'utilisateur derrière, pas d'expiration, pas de scopes fins, et elle finit dans les dépôts Git. Pour de l'accès au nom d'une personne, c'est OAuth ; pour du machine à machine sérieux, Client Credentials avec tokens courts.",[275],{"id":406,"tags":407,"question":409,"quick_answer":410,"details":411,"dependsOn":412,"difficulty":77},"auth-044",[7,5,408],"autorisation","Qu'est-ce que le **RBAC** ?","Role-Based Access Control : les permissions vont aux rôles, les utilisateurs reçoivent des rôles","`admin` peut tout, `editor` peut écrire, `viewer` peut lire. On ne gère jamais les permissions utilisateur par utilisateur.\n\nQuand les règles dépendent du contexte (« un manager voit les notes de **son** équipe »), on passe à l'**ABAC** (attributs : département, propriétaire, heure) ou à des politiques (OPA, Cedar).",[42],{"id":414,"tags":415,"question":417,"quick_answer":418,"details":419,"dependsOn":420,"difficulty":139,"sources":421},"auth-045",[7,5,35,416],"passkeys","Qu'est-ce qu'une **passkey** ?","Une paire de clés par site, stockée sur l'appareil : le site garde la publique, la privée signe un défi","Standard **WebAuthn / FIDO2**. À l'inscription, l'appareil crée une clé privée (protégée par biométrie ou PIN) et donne la clé publique au site. À la connexion, le site envoie un défi aléatoire, l'appareil le signe.\n\nRien à retenir, rien à voler côté serveur (une clé publique ne sert à rien), et **résistant au phishing** : la clé est liée au domaine (le RP ID), un site imitateur ne reçoit aucune signature valide.",[50],[422],{"title":423,"url":424},"W3C — Web Authentication Level 3, Relying Party identifier","https://www.w3.org/TR/webauthn-3/",{"id":426,"tags":427,"question":428,"quick_answer":429,"details":430,"dependsOn":431,"difficulty":64,"sources":432},"auth-046",[7,5,35,59],"Qu'est-ce que le **TOTP** ?","Un code à 6 chiffres calculé depuis un secret partagé et l'heure courante, renouvelé toutes les 30 secondes","Time-based One-Time Password (RFC 6238). Le QR code scanné dans Google Authenticator ou Bitwarden contient le secret. Serveur et application calculent `HMAC(secret, heure/30)` et comparent.\n\nSecond facteur « possession ». Plus sûr que le SMS (SIM swapping), mais toujours sensible au phishing en temps réel, contrairement aux passkeys.",[50],[433],{"title":434,"url":435},"RFC 6238 — TOTP","https://datatracker.ietf.org/doc/html/rfc6238",{"id":437,"tags":438,"question":439,"quick_answer":440,"details":441,"dependsOn":442,"difficulty":139,"sources":443},"auth-047",[7,5,177,35],"Comment un resource server vérifie-t-il un access token **opaque** (non JWT) ?","En appelant l'endpoint d'introspection de l'authorization server","RFC 7662 : un `POST` sur l'endpoint d'introspection (typiquement `/introspect`) avec le token → `{ \"active\": true, \"sub\": …, \"scope\": … }`. L'API ne peut rien lire dans le token elle-même : c'est une chaîne aléatoire, référence à un état côté serveur d'autorisation.\n\nAvantages : révocation immédiate, rien n'est exposé. Inconvénient : un appel réseau par requête (à mettre en cache).",[219,168],[444],{"title":445,"url":446},"RFC 7662 — Token Introspection","https://datatracker.ietf.org/doc/html/rfc7662",{"id":448,"tags":449,"question":450,"quick_answer":451,"details":452,"dependsOn":453,"difficulty":64},"auth-048",[7,5,72,35],"Que fait l'attribut **SameSite** sur un cookie ?","Il limite l'envoi du cookie dans les requêtes qui viennent d'un autre site : protection CSRF","- `Strict` : jamais envoyé depuis un autre site, même en suivant un lien (l'utilisateur arrive déconnecté)\n- `Lax` : envoyé sur les navigations de premier niveau (clic sur un lien, GET), pas sur les POST ou les sous-requêtes cross-site. Défaut des navigateurs modernes\n- `None` : toujours envoyé, exige `Secure`\n\n`Lax` suffit contre le CSRF classique tant que les actions sensibles ne sont pas en GET.",[79],{"id":455,"tags":456,"question":457,"quick_answer":458,"details":459,"dependsOn":460,"difficulty":139,"sources":461},"auth-049",[7,5,96,177,35],"Qu'est-ce que la **rotation** du refresh token ?","Chaque usage du refresh token en émet un nouveau et invalide l'ancien","Si un refresh token volé est utilisé après que le légitime l'a déjà échangé, le serveur voit un token déjà consommé : il révoque toute la famille et force un nouveau login. C'est la détection de vol recommandée par le Security BCP pour les clients publics.",[175],[462],{"title":463,"url":260},"RFC 9700 — OAuth 2.0 Security BCP, refresh tokens",{"id":465,"tags":466,"question":467,"quick_answer":468,"details":469,"dependsOn":470,"difficulty":48},"auth-050",[7,5,192],"Différence entre un **401** et un **403** ?","401 : pas (ou mal) authentifié. 403 : authentifié, mais pas autorisé","`401 Unauthorized` est mal nommé : il veut dire « identifie-toi » et s'accompagne d'un en-tête `WWW-Authenticate`. Réessayer avec un token valide peut marcher.\n\n`403 Forbidden` : le serveur sait qui tu es et refuse quand même. Réessayer avec les mêmes identifiants ne changera rien.",[42],{"id":472,"tags":473,"question":474,"quick_answer":475,"details":476,"dependsOn":477,"difficulty":64},"auth-051",[7,5,96,107],"Pourquoi vérifier le claim **iss** d'un JWT ?","Pour n'accepter que les jetons des émetteurs attendus, même si la signature est valide","Une API qui fait confiance à plusieurs fournisseurs d'identité doit savoir lequel a signé : elle choisit le JWKS correspondant à `iss`, et refuse un `iss` inconnu avant même de vérifier la signature.\n\nSans ça, n'importe quel serveur OIDC public pourrait émettre des jetons acceptés par l'API.",[113,350],"ok",null,1792059302098]