Configuration du fournisseur
- Leçon 10
- 50 min
- Module 3 : Sessions et intégration à l'application
Leçon 10 sur 19 · Authentification, autorisations et applications multilocatairesConfiguration du fournisseur
1. Bases de l'identité et des autorisations
2. Comprendre la connexion et les jetons
3. Sessions et intégration à l'application
4. Contrôler l'accès aux ressources
5. Travail en arrière-plan et administration
6. Valider et documenter la conception
Ce que vous saurez faire
Faites correspondre les paramètres du fournisseur et de l’API, un par un. Vérifiez cette correspondance avec une commande avant toute connexion. Ensuite, connectez la même API à un vrai fournisseur d’identité et découvrez ce qu’un fournisseur simulé peut cacher.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- La connexion dans le navigateur et son témoin, dans Choix de session dans le navigateur.
- Les façons de terminer une session et la déconnexion du fournisseur, dans Cycle de vie d’une session.
- L’émetteur, l’audience et le type de jeton, dans Ce que signifie un jeton.
Ce qu’il vous faut sur votre ordinateur
- Le projet après Cycle de vie d’une session, avec le fournisseur et l’API en marche.
- Facultatif, pour le vrai fournisseur : Docker avec environ 1 Go de mémoire libre et 750 Mo d’espace disque pour l’image Keycloak. Vous n’avez besoin ni de compte ni d’argent, et vous supprimez tout à la fin.
Testé sur macOS (Apple silicon) avec Keycloak 26.8.0. Les commandes Windows sont écrites, mais pas testées. La description de Microsoft Entra ID vient de la documentation de Microsoft et n’a pas été testée.
Un colis et une adresse
Section intitulée « Un colis et une adresse »Vous commandez un livre en ligne. La boutique donne votre nom et votre adresse au livreur, qui apporte le colis uniquement à cette adresse. Si un chiffre du numéro de porte est erroné, le livreur ne laisse pas le colis chez un voisin sympathique. Le colis retourne au dépôt, et vous attendez.
Les deux côtés doivent avoir les mêmes renseignements. La boutique a noté l’adresse à la création de votre compte; le livreur la lit sur l’étiquette. Personne ne remarque une erreur avant qu’un colis n’arrive pas. Et la règle « uniquement à l’adresse inscrite » assure la sécurité de la livraison.
Le problème : un caractère, et personne ne peut se connecter
Section intitulée « Le problème : un caractère, et personne ne peut se connecter »La connexion de ce module compte environ dix paramètres répartis entre deux côtés. Le fournisseur conserve une fiche de l’application, et l’API conserve son propre .env. Un seul caractère différent bloque toutes les connexions, et l’erreur apparaît à un endroit différent chaque fois.
L’auteur a changé un paramètre à la fois dans un projet fonctionnel. Voici trois résultats réels :
OIDC_REDIRECT_URIindiquaithttp://localhost:8000/auth/callbackau lieu dehttp://127.0.0.1:8000/auth/callback. Les deux noms désignent le même ordinateur, mais leur texte diffère. Le navigateur s’est arrêté chez le fournisseur, avec un code 400 et{"error":"invalid_request","error_description":"This redirect URI is not registered for the application."}(cette URI de redirection n’est pas inscrite pour l’application). L’API n’a rien reçu.OIDC_CLIENT_SECRETétait incorrect. La page de connexion fonctionnait, Sam choisissait son nom, puis le rappel de l’API répondait400 login_failed(échec de connexion) : « Le fournisseur a refusé le code : invalid_client. »OIDC_AUDIENCEindiquaitbilling-api. Tout fonctionnait jusqu’à la vérification des jetons par l’API :400 login_failed, « Les jetons ne sont pas valides : le jeton n’est pas destiné à billing-api. »
Trois causes, trois endroits, et chaque fois, la personne devant le navigateur voit seulement que « ça ne fonctionne pas ».
L’idée : une inscription d’application et son équivalent dans .env
Section intitulée « L’idée : une inscription d’application et son équivalent dans .env »Un fournisseur connecte les personnes uniquement aux applications qu’il connaît. Sa fiche pour une application est l’inscription d’application (Keycloak dit « client »; Microsoft dit « app registration », ou inscription d’application). L’API conserve les mêmes renseignements dans ses paramètres. Chacun a un rôle :
- Identifiant du client (
help-desk-web) : le nom de l’application dans chaque requête. - Type de client et secret : un client confidentiel, comme un serveur d’application, peut conserver un secret. Ce secret prouve qu’une demande de jeton vient de l’application. Un client public, comme
ticket-clisur votre ordinateur, n’a aucun secret et utilise uniquement PKCE. - URI de redirection : les seules adresses qui peuvent recevoir des codes. Un fournisseur n’envoie jamais de code à une adresse absente de la liste. De même, le livreur ne laisse jamais un colis à la mauvaise porte.
- URI de redirection après déconnexion : où le fournisseur peut envoyer le navigateur après sa propre déconnexion.
- Origines autorisées (CORS) : les autres sites dont le JavaScript peut appeler l’API. La page du service de soutien est sur le site de l’API, donc la liste est vide :
ALLOWED_ORIGINSreste non défini. - Portées et audience : ce que l’application peut demander et l’API à laquelle les jetons d’accès sont destinés (
ticket-api). - Émetteur et clés : qui signe les jetons et où se trouvent les clés publiques.
Description textuelle du diagramme
Lisez chaque ligne comme une paire. La case de gauche contient un renseignement du fournisseur; celle de droite indique où l’API conserve le même renseignement. L’étiquette montre ce que reçoit la personne devant le navigateur quand les deux diffèrent. Seule l’URI de redirection provoque un échec chez le fournisseur, avant la création d’un code. Les autres échecs surviennent plus tard, au rappel de l’API, quand elle vérifie ce qu’elle a reçu.
Un petit exemple : l’inscription d’exercice
Section intitulée « Un petit exemple : l’inscription d’exercice »Le fournisseur d’exercice conserve ses inscriptions dans .idp/clients.json. Ouvrez ce fichier. L’entrée du service de soutien ressemble à ceci (votre secret_sha256 est différent) :
{ "client_id": "help-desk-web", "name": "Help desk (web)", "type": "confidential", "grant_types": ["authorization_code", "refresh_token"], "redirect_uris": ["http://127.0.0.1:8000/auth/callback"], "post_logout_redirect_uris": ["http://127.0.0.1:8000/app/"], "scopes": ["openid", "profile", "email", "offline_access", "tickets:read", "tickets:write", "members:manage"], "secret_sha256": "a595db1059bb4466f0162c6e0d2ede1e0a8d354cbaccd8d420857348c815d0c8"}Comparez-la avec votre .env. OIDC_CLIENT_ID=help-desk-web correspond à la première ligne. OIDC_REDIRECT_URI correspond à l’unique entrée de redirect_uris, caractère pour caractère. OIDC_CLIENT_SECRET est le secret dont le SHA-256 figure à la dernière ligne. Comme la table des sessions de l’API, le fournisseur conserve seulement une empreinte. Les portées comprennent offline_access, qui permet le jeton de renouvellement de la dernière leçon.
Larkfield : vérifier les deux côtés avec une commande
Section intitulée « Larkfield : vérifier les deux côtés avec une commande »Amira ne veut pas découvrir une différence par l’intermédiaire d’une personne qui ne peut pas se connecter. Le projet comprend une vérification qui demande au fournisseur ce qu’une vraie connexion rencontrerait, paramètre par paramètre. Elle ne change rien.
-
Copiez la vérification, le document d’identité et les fichiers facultatifs du vrai fournisseur depuis l’instantané :
Fenêtre de terminal S=../nextia-learning-labs/C23/snapshots/end-of-m03mkdir -p docs optionalcp "$S/scripts/check_identity.py" scripts/cp "$S/docs/identity-config.md" docs/cp -R "$S/optional/keycloak" optional/Fenêtre de terminal $S = "..\nextia-learning-labs\C23\snapshots\end-of-m03"New-Item -ItemType Directory -Force docs, optional | Out-NullCopy-Item "$S\scripts\check_identity.py" scripts\Copy-Item "$S\docs\identity-config.md" docs\Copy-Item -Recurse "$S\optional\keycloak" optional\Votre projet correspond maintenant à l’instantané
end-of-m03, fichier pour fichier. -
Avec le fournisseur en marche, lancez la vérification :
Fenêtre de terminal python -m scripts.check_identitySign-in settings:OK issuer: .env says http://localhost:8400, the provider says http://localhost:8400OK published keys: 1 (1 for RS256)OK the provider supports PKCEOK application help-desk-web with redirect URI http://127.0.0.1:8000/auth/callback: 200OK client secret: the provider answers 'invalid_grant' to a made-up codeOK SESSION_KEY is setOK cookie Secure=False, redirect URI over HTTPOK audience: ticket-apiallowed origins (CORS): none (same site only)0 problem(s).Si vous avez publié une deuxième clé dans Lire un jeton : JWT, signatures et clés sans retirer l’ancienne, la ligne des clés indique
2 (2 for RS256)(2, dont 2 pour RS256). C’est aussi correct.Regardez la ligne du secret du client. La vérification envoie un code inventé avec le vrai secret.
invalid_grant(autorisation invalide) signifie « le code est incorrect » : le fournisseur a donc accepté le secret.invalid_client(client invalide) indiquerait un secret incorrect. -
Rendez un paramètre incorrect pour une seule exécution. Une variable d’environnement a priorité sur
.env, donc le fichier ne change pas :Fenêtre de terminal OIDC_REDIRECT_URI=http://localhost:8000/auth/callback python -m scripts.check_identityFenêtre de terminal $env:OIDC_REDIRECT_URI = "http://localhost:8000/auth/callback"; python -m scripts.check_identity; Remove-Item Env:OIDC_REDIRECT_URIPROBLEM application help-desk-web with redirect URI http://localhost:8000/auth/callback: 400Register this exact redirect URI for the application at the provider.Les autres lignes restent correctes, et la dernière indique
1 problem(s).(1 problème). Essayez aussiOIDC_CLIENT_SECRET=not-the-secret:PROBLEM client secret: the provider answers 'invalid_client' to a made-up codeinvalid_client means the secret (OIDC_CLIENT_SECRET) is wrong or missing. -
Arrêtez le fournisseur (Ctrl+C dans son terminal) et relancez la vérification. Elle s’arrête à la première ligne, car elle ne peut rien vérifier d’autre :
Sign-in settings:PROBLEM discovery at http://localhost:8400: [Errno 61] Connection refusedIs the provider running? python -m idpSur Windows et Linux, le numéro et le texte de l’erreur diffèrent. Redémarrez le fournisseur.
-
Ouvrez
docs/identity-config.md. Deux tableaux y présentent tous les paramètres des deux côtés, avec les valeurs d’exercice et leur raison d’être. Une autre équipe peut configurer l’API avec ce document. Remise du travail l’utilise.
Un vrai fournisseur : Keycloak dans Docker (facultatif)
Section intitulée « Un vrai fournisseur : Keycloak dans Docker (facultatif) »Le fournisseur d’exercice respecte les normes, mais il a été écrit pour ce cours. Un fournisseur simulé s’accorde avec le code développé à ses côtés et peut donc cacher des erreurs. Pour les trouver, exécutez un vrai fournisseur une fois. Keycloak est un fournisseur d’identité libre (licence Apache-2.0) qui fonctionne dans Docker sur votre ordinateur, sans compte. Son mode de développement conserve tout en mémoire et utilise HTTP sans chiffrement. Il ne doit jamais contenir de vraies personnes.
Ce parcours est facultatif; le reste du cours utilise le fournisseur d’exercice. Prévoyez environ 20 minutes.
-
Démarrez Keycloak. Choisissez votre propre mot de passe d’administration au lieu de
choose-one:Fenêtre de terminal docker run -d --name ticket-keycloak -p 127.0.0.1:8480:8080 \-e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=choose-one \quay.io/keycloak/keycloak:26.8.0 start-devFenêtre de terminal docker run -d --name ticket-keycloak -p 127.0.0.1:8480:8080 `-e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=choose-one `quay.io/keycloak/keycloak:26.8.0 start-devAttendez environ une minute, jusqu’à ce que http://127.0.0.1:8480 réponde dans votre navigateur.
-
Créez le realm (domaine d’identité), l’inscription et une personne fictive avec le script du projet. Il utilise l’API d’administration de Keycloak :
Fenêtre de terminal KEYCLOAK_ADMIN_PASSWORD=choose-one python optional/keycloak/setup.pyFenêtre de terminal $env:KEYCLOAK_ADMIN_PASSWORD = "choose-one"; python optional/keycloak/setup.pyKeycloak is ready. Put these lines in .env (instead of the practice provider's):OIDC_ISSUER=http://127.0.0.1:8480/realms/helpdeskOIDC_CLIENT_ID=help-desk-webOIDC_CLIENT_SECRET=<a secret made by Keycloak>ACCESS_TOKEN_TYPES=JWTSign in as sam with the password <a random password> (made up; shown once).Keycloak's user ID for sam (the token's sub): 364a4212-e593-464b-8055-bcd9773134e9Give it a membership, for example:INSERT INTO users (user_id, name, email) VALUES ('364a4212-e593-464b-8055-bcd9773134e9', 'Sam (Keycloak)', 'sam.keycloak@larkfield.example');INSERT INTO memberships (tenant_id, user_id, role) VALUES ('larkfield', '364a4212-e593-464b-8055-bcd9773134e9', 'staff');Votre secret, votre mot de passe et votre identifiant d’utilisateur diffèrent. Gardez la sortie ouverte.
-
Dans
.env, placez#devant vos lignes d’exerciceOIDC_ISSUERetOIDC_CLIENT_SECRET. Ajoutez les lignesOIDC_ISSUERetOIDC_CLIENT_SECRETaffichées.OIDC_CLIENT_ID=help-desk-webest déjà dans.envavec la même valeur, donc ne l’ajoutez pas une deuxième fois. N’ajoutez pas encoreACCESS_TOKEN_TYPES=JWT: la prochaine étape montre pourquoi il est nécessaire. Redémarrezfastapi dev. -
Ouvrez http://127.0.0.1:8000/app/ et choisissez Sign in (se connecter). Cette fois, une vraie page de connexion demande un mot de passe :

Le même bouton Sign in (se connecter), maintenant avec un vrai fournisseur : Keycloak demande le mot de passe de la personne fictive. L'API ne le voit jamais. L’image est en anglais. Connectez-vous comme
samavec le mot de passe affiché. Vous revenez à l’API avec une erreur :{"error":{"code":"login_failed","message":"The tokens are not valid: This is not an access token (an ID token is for the application, not the API).", … }}Les jetons d’accès de Keycloak ont
typ: JWTdans leur en-tête, plutôt queat+jwtcomme ceux du fournisseur d’exercice. La vérification supplémentaire peu coûteuse de l’API, présentée dans Ce que signifie un jeton, les a refusés. -
Ajoutez
ACCESS_TOKEN_TYPES=JWTà.env, redémarrezfastapi dev, puis reconnectez-vous. Vous arrivez sur/app/. La page affiche l’identifiant Keycloak de Sam, un UUID, avec"memberships": []. Le Sam de Keycloak est une nouvelle personne pour l’API. Leusr-samd’exercice et lui partagent un nom et une adresse courriel, mais pas unsub. -
La connexion a déjà ajouté la ligne de Sam à
users. Exécutez donc seulement le deuxièmeINSERTaffiché, celui de l’adhésion, danspsql(docker compose exec db psql -U tickets). Rechargez la page. Maintenant,membershipscontientlarkfield,Larkfield,staff. -
Exécutez
python -m scripts.check_identity. Les 8 lignes indiquent OK pour Keycloak, et la dernière indique0 problem(s).(0 problème). Choisissez ensuite Sign out (se déconnecter). La réponse de l’API indique l’adresse de fin de session de Keycloak,http://127.0.0.1:8480/realms/helpdesk/protocol/openid-connect/logout. La page y envoie le navigateur. -
Supprimez tout :
Fenêtre de terminal docker rm -f ticket-keycloakDans
.env, retirez les quatre lignes Keycloak et le#devant vos lignes d’exercice. Redémarrezfastapi devet vérifiez avecpython -m scripts.check_identity.
setup.py a aussi créé deux paramètres dans Keycloak dont le fournisseur d’exercice n’a pas besoin. Un mappage d’audience place ticket-api dans le aud des jetons d’accès de Keycloak. Le client reçoit aussi la portée basic de Keycloak, qui ajoute sub. Sans elle, l’API refuse le jeton avec « Le jeton n’a pas de revendication sub ».
Pourquoi ACCESS_TOKEN_TYPES=JWT ne laisse-t-il pas entrer les jetons d’identité? Parce que la vérification de l’audience reste active. L’audience d’un jeton d’identité est l’application, help-desk-web; l’API accepte seulement ticket-api. La vérification du type était un ajout peu coûteux; celle de l’audience est essentielle.
Deux vrais bogues que le fournisseur simulé avait cachés
Section intitulée « Deux vrais bogues que le fournisseur simulé avait cachés »Quand l’auteur du cours a connecté Keycloak pour la première fois, la connexion a échoué deux fois. Les deux bogues étaient dans l’API, et le fournisseur d’exercice avait accepté les deux. Ils sont corrigés dans votre copie. L’auteur a recréé chacun d’eux volontairement pour montrer les vrais messages.
Premier bogue : un vérificateur PKCE trop court. La première version de l’API créait le vérificateur avec secrets.token_urlsafe(24) : 32 caractères. La norme PKCE (RFC 7636) exige de 43 à 128 caractères. Le fournisseur d’exercice ne vérifiait pas la longueur, donc tous les tests réussissaient. Keycloak la vérifie :
{"error":"invalid_grant","error_description":"PKCE verification failed: Invalid code verifier"}La personne devant le navigateur voyait seulement 400 login_failed : « Le fournisseur a refusé le code : invalid_grant. » La correction tient en une ligne dans sessions.py : secrets.token_urlsafe(48), soit 64 caractères. Le fournisseur d’exercice vérifie maintenant la longueur aussi, et un test le prouve. Avec 32 caractères, il répond : « Le code_verifier doit avoir de 43 à 128 caractères (A-Z a-z 0-9 - . _ ~). »
Deuxième bogue : une adresse courriel qui devait être unique. Le deuxième bogue est le cas d’échec ci-dessous.
La leçon des deux bogues est la même. Un fournisseur simulé que vous écrivez partage vos hypothèses. Testez une fois avec un vrai fournisseur avant que des personnes dépendent de la connexion, même si vous le supprimez ensuite.
Erreur courante
La première connexion avec un vrai fournisseur échoue avec un code 500
Symptôme : avec Keycloak, Sam entre son mot de passe, et le rappel de l’API répond 500 internal_error (erreur interne), « Une erreur s’est produite sur le serveur. » Le fournisseur d’exercice ne provoquait jamais cette erreur.
Cause : la première version de la table users avait une contrainte UNIQUE sur email. Le Sam de Keycloak a un nouvel identifiant, mais la même adresse que le usr-sam d’exercice, sam@larkfield.example. À la première connexion, l’API ajoute une ligne pour chaque nouvelle personne, et l’insertion a enfreint la contrainte. Le journal de l’API indiquait :
psycopg.errors.UniqueViolation: duplicate key value violates unique constraint "users_email_unique"DETAIL: Key (email)=(sam@larkfield.example) already exists.Diagnostic : une erreur 500 a toujours une ligne de journal. Cherchez Error (erreur) dans le terminal de l’API, près de l’heure du rappel. Le nom d’une contrainte dans le message vous indique quelle règle a été enfreinte.
Correction : une adresse courriel est une coordonnée, jamais la clé d’une personne. La clé d’une personne est le sub du fournisseur. Deux fournisseurs ou deux comptes peuvent partager une adresse, et une personne peut la changer. La migration 013 de votre projet contient un index normal sur lower(email), pas un index unique. Le cours l’a modifiée avant qu’un apprenant l’applique. Après l’exécution, la base de données de l’auteur contenait 2 personnes avec sam@larkfield.example, et les deux pouvaient se connecter.
Microsoft Entra ID : les mêmes paramètres, d’autres noms (non testé)
Section intitulée « Microsoft Entra ID : les mêmes paramètres, d’autres noms (non testé) »Plusieurs entreprises utilisent Microsoft Entra ID, le service d’identité de Microsoft 365 et d’Azure. Ce cours ne l’a pas testé : il exige un compte Azure, et le cours n’en utilise aucun. Le tableau associe les paramètres à partir de la documentation de Microsoft. Vérifiez-les avec un vrai jeton avant de vous y fier.
| Ce dont l’API a besoin | Fournisseur d’exercice | Microsoft Entra ID (selon la documentation) |
|---|---|---|
| Identifiant du client | help-desk-web |
l’Application (client) ID (identifiant de l’application cliente) d’une app registration (inscription d’application), un UUID |
| Secret du client | fourni par python -m idp init |
Certificates & secrets (certificats et secrets) → un nouveau secret du client, affiché une seule fois |
| URI de redirection | http://127.0.0.1:8000/auth/callback |
Authentication (authentification) → une plateforme de type Web avec cette URI |
| Audience | ticket-api |
Expose an API (exposer une API) : une Application ID URI (URI d’identifiant d’application), par exemple api://ticket-api, et des portées comme tickets.read |
| Émetteur | http://localhost:8400 |
https://login.microsoftonline.com/<directory ID>/v2.0, quand le manifeste définit requestedAccessTokenVersion à 2 |
| Type de jeton | at+jwt |
JWT : définissez ACCESS_TOKEN_TYPES=JWT |
| Portées dans le jeton | scope |
scp (l’API lit les deux) |
| Identifiant de la personne | sub |
sub diffère pour chaque application; oid est identique dans toutes les applications de l’annuaire. Cette API utilise sub |
Deux différences comptent pour cette API. Les noms de portées contenant : peuvent nécessiter d’autres noms, comme tickets.read. Les vérifications de portées de l’API devraient alors utiliser les mêmes noms. De plus, les jetons d’accès version 2 d’Entra ID peuvent contenir l’identifiant du client de l’API dans aud, plutôt que l’Application ID URI. Décodez un vrai jeton avec scripts.token decode et définissez OIDC_AUDIENCE selon ce que vous voyez.
À vous de jouer : une deuxième adresse pour l’API
Section intitulée « À vous de jouer : une deuxième adresse pour l’API »Lancez une deuxième copie de l’API sur le port 8001, par exemple pour essayer un changement sans arrêter la copie actuelle. N’arrêtez rien. Dans un nouveau terminal, avec l’environnement virtuel actif :
OIDC_REDIRECT_URI=http://127.0.0.1:8001/auth/callback POST_LOGOUT_REDIRECT_URI=http://127.0.0.1:8001/app/ fastapi dev --port 8001$env:OIDC_REDIRECT_URI = "http://127.0.0.1:8001/auth/callback"; $env:POST_LOGOUT_REDIRECT_URI = "http://127.0.0.1:8001/app/"; fastapi dev --port 8001Prédisez ce que http://127.0.0.1:8001/app/ → Sign in (se connecter) affiche. Ensuite, faites fonctionner la connexion en modifiant seulement la configuration du fournisseur. Ne modifiez pas l’API.
Afficher la réponse
Le navigateur s’arrête chez le fournisseur avec 400 et « This redirect URI is not registered for the application. » (cet URI de redirection n’est pas enregistré pour l’application). Le fournisseur n’a que le port 8000 dans sa liste. Il n’envoie aucun code à une adresse qui n’y figure pas.
Ajoutez la nouvelle adresse à la liste dans .idp/clients.json, dans l’entrée de help-desk-web :
"redirect_uris": ["http://127.0.0.1:8000/auth/callback", "http://127.0.0.1:8001/auth/callback"],"post_logout_redirect_uris": ["http://127.0.0.1:8000/app/", "http://127.0.0.1:8001/app/"],Le fournisseur d’exercice lit le fichier à chaque requête. La prochaine connexion fonctionne donc sans redémarrage. L’auteur a fait la même chose avec un deuxième port. La connexion sur ce port s’est terminée par Set-Cookie: ticket_session=…, comme d’habitude. Supprimez les deux nouvelles entrées quand vous avez terminé : chaque adresse enregistrée est un endroit de plus où envoyer des codes.
Quand utiliser un fournisseur simulé ou réel, et ce que chacun coûte
Section intitulée « Quand utiliser un fournisseur simulé ou réel, et ce que chacun coûte »Utilisez le fournisseur d’exercice pour le développement et les tests. Il ne nécessite aucun compte et démarre immédiatement. Une seule commande permet de créer des utilisateurs, de les désactiver et de faire la rotation des clés. Son coût est celui que vous avez vu : il partage vos hypothèses.
Utilisez un vrai fournisseur avant que des personnes dépendent de la connexion, puis à nouveau quand vous changez de fournisseur. Keycloak dans Docker est gratuit et local, et vous pouvez le supprimer avec une seule commande. Le fournisseur d’une entreprise (Entra ID ou un autre) demande un compte et un administrateur qui enregistre l’application. Il faut aussi du temps pour chaque changement. En échange, il apporte ce qu’un fournisseur simulé n’a jamais : de vrais mots de passe et un deuxième facteur. Il offre aussi la récupération de compte et un audit des connexions. Ce sont les responsabilités du fournisseur, pas celles de l’API.
Vérifiez votre compréhension
Le fournisseur refuse d'envoyer un code à un URI de redirection non enregistré et affiche plutôt une page d'erreur. Pourquoi une page d'erreur est-elle plus sûre qu'une redirection vers cette adresse?
Afficher la réponse
Le code est l’étape qui précède les jetons. Supposons que le fournisseur redirige vers n’importe quelle adresse dans la requête. Un attaquant pourrait lancer une connexion avec sa propre adresse comme redirect_uri et envoyer le lien à Sam. Après la connexion de Sam, l’attaquant reçoit le code de Sam. La liste des adresses enregistrées limite l’envoi des codes aux adresses que l’application possède. Une page d’erreur n’envoie rien nulle part : la personne voit un problème, et aucun code n’existe.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Prédisez : avec Keycloak et les paramètres par défaut de l'API, la connexion échoue avec « This is not an access token » (ce n'est pas un jeton d'accès). Vous définissez ACCESS_TOKEN_TYPES=JWT. Quelqu'un peut-il maintenant utiliser le jeton d'identité de Keycloak pour appeler l'API? Expliquez.
Afficher la réponse
Non. La vérification du type n’était qu’un premier filtre peu coûteux. Le jeton d’identité de Keycloak a pour audience help-desk-web, l’application. L’API accepte seulement les jetons dont l’audience est ticket-api. La vérification de l’audience refuse donc le jeton d’identité. Keycloak ajoute ticket-api aux jetons d’accès seulement parce que setup.py a créé une règle de correspondance d’audience. La vérification essentielle porte sur l’audience, pas sur le type.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Exercice pratique : exécutez python -m scripts.check_identity, puis rendez un paramètre incorrect avec une variable d'environnement. Expliquez ce que la vérification a fait pour chaque ligne OK (correct) concernant le fournisseur. Expliquez aussi ce qu'une personne verrait dans le navigateur avec le paramètre incorrect.
Afficher la réponse
La vérification a lu le document de découverte du fournisseur et comparé son issuer (émetteur) à OIDC_ISSUER. Elle a récupéré les clés à jwks_uri et compté celles de type RS256, puis lu les méthodes PKCE. Elle a ouvert l’adresse d’autorisation avec l’identifiant client et l’URI de redirection (200 signifie que les deux sont connus). Elle a envoyé un code inventé avec le secret client : invalid_grant (autorisation invalide) signifie que le secret a été accepté. Avec un URI de redirection incorrect, la personne voit l’erreur 400 du fournisseur : « This redirect URI is not registered for the application. » Avec un secret incorrect, elle choisit son nom, puis reçoit 400 login_failed (échec de connexion) de l’API. Le message est « The provider refused the code : invalid_client. » (le fournisseur a refusé le code : client invalide).
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- L’enregistrement de l’application chez le fournisseur et le fichier
.envde l’API décrivent les mêmes faits, de l’émetteur au type de jeton. Un seul caractère différent bloque toutes les connexions. python -m scripts.check_identityvérifie les faits auprès du fournisseur avant toute connexion;docs/identity-config.mdles répertorie pour une autre équipe.- Un URI de redirection incorrect échoue chez le fournisseur, avant qu’un code existe. Les autres différences échouent au point de retour de l’API avec
400 login_failed. - Keycloak 26.8.0 dans Docker a fonctionné avec
ACCESS_TOKEN_TYPES=JWT, une règle de correspondance d’audience et sa portéebasic(poursub). Ses utilisateurs ont besoin de leurs propres adhésions, car leursubest nouveau. - Le vrai fournisseur a révélé deux bogues que le fournisseur simulé avait cachés. Le vérificateur PKCE avait 32 caractères, au lieu de 43 à 128. Une adresse courriel unique a causé une erreur 500 à la première connexion. Le courriel est une coordonnée;
subest la clé. - Microsoft Entra ID utilise les mêmes paramètres sous d’autres noms. La description présentée ici vient de sa documentation, sans avoir été testée.
Le module 3 est terminé : les personnes se connectent par l’API avec un témoin (cookie). Les sessions se terminent à temps, et les paramètres du fournisseur sont vérifiés. Le module 4 utilise l’identité pour décider ce que chaque personne peut faire, dans quelle organisation, sur chaque route.
Leçon suivante : L'autorisation dans l'API