Chapitre 9.5 — Enregistrement & claims
⏱️ TL;DR — Avant tout lancement, plateforme et outil doivent se connaître : c’est l’enregistrement (registration). On y échange des identifiants (
client_id,deployment_id), des URLs (login, redirect, endpoints d’auth et de jetons,jwks_uride chacun). Cet échange est manuel (on se transmet les valeurs) ou automatique (Dynamic Registration). Une fois enregistrés, chaque lancement transporte, dans leid_token, des claims namespacés (.../claim/message_type,.../claim/roles,.../claim/context,.../claim/resource_link…) que ton outil lit après validation. Ce chapitre relie les deux : d’abord se connaître, ensuite lire.
🎯 Objectifs
- Lister ce qu’échangent plateforme et outil à l’enregistrement.
- Distinguer enregistrement manuel et Dynamic Registration.
- Lire les claims LTI d’un
id_token: type de message, rôles, contexte, resource link, custom. - Interpréter correctement les rôles (URIs) et le champ
sub(identité stable).
L’enregistrement : se connaître avant de se parler
Un lancement LTI 1.3 ne peut fonctionner que si chaque partie détient les coordonnées de l’autre. L’enregistrement, c’est cet échange préalable et unique (par intégration). Concrètement, chacun fournit un jeu d’informations :
Ce que l’OUTIL fournit à la plateforme :
| Élément | Rôle |
|---|---|
| OIDC login initiation URL | Où la plateforme envoie l’amorce (temps 1) |
| Redirect URI(s) | Où la plateforme POST le id_token (temps 3) — pré-enregistrées |
jwks_uri de l’outil (ou une clé publique) | Pour que la plateforme vérifie les appels de l’outil (renvoi de note, Partie 10) |
| Target link URI | L’URL de lancement par défaut |
Ce que la PLATEFORME fournit à l’outil :
| Élément | Rôle |
|---|---|
Issuer (iss) | L’identité de la plateforme (à vérifier dans iss) |
client_id | L’identifiant de ton outil chez cette plateforme (à vérifier dans aud) |
| OIDC authorization endpoint | Où l’outil redirige (temps 2) |
| OAuth2 token endpoint | Où l’outil obtient un jeton pour appeler les services (AGS/NRPS, Partie 10) |
jwks_uri de la plateforme | Pour vérifier la signature du id_token |
deployment_id | Identifie un déploiement précis (un même client_id peut avoir plusieurs déploiements) |
💡 Réflexe — Range ces valeurs dans une configuration par plateforme, indexée par
iss(+client_id/deployment_idsi besoin). À chaque lancement, tu retrouves la bonne config via leissreçu à l’amorce. Un outil qui sert plusieurs établissements gère donc N configurations — d’où l’importance d’unissfiable dès le temps 1.
client_id vs deployment_id
Deux identifiants proches à ne pas confondre :
- Le
client_ididentifie ton outil auprès de la plateforme (l’« application »). - Le
deployment_ididentifie une instance de déploiement de cet outil dans la plateforme. Une même plateforme peut déployer ton outil à plusieurs endroits (plusieurs facultés, plusieurs espaces) : mêmeclient_id,deployment_iddifférents. Ledeployment_idarrive aussi dans un claim duid_token, à recouper avec ta config.
Manuel ou dynamique
L’échange se fait de deux façons :
- Enregistrement manuel : on se transmet les valeurs (formulaires d’admin, copier-coller d’URLs et d’identifiants). Simple, mais fastidieux à l’échelle de dizaines de clients.
- Dynamic Registration : un protocole (fondé sur l’OpenID Connect Dynamic Registration) qui automatise l’échange — l’admin de la plateforme colle une seule URL de ton outil, et les deux systèmes s’échangent tout le reste automatiquement. C’est le confort moderne, très apprécié des administrateurs.
🔌 Côté intégration — Proposer le Dynamic Registration est un argument commercial : au lieu d’un tutoriel de dix étapes à faire suivre à chaque établissement, l’admin colle une URL et c’est branché. Moins de support, moins d’erreurs de config (les fameuses
redirect_urimal recopiées du chapitre 9.4), adoption plus rapide. Beaucoup de LMS récents le supportent.
Lire les claims d’un lancement
Une fois le id_token validé (chapitre 9.4), tu lis ses claims. Les claims LTI sont namespacés sous https://purl.imsglobal.org/spec/lti/claim/. Voici un id_token de lancement (payload, extrait complet) :
{
"iss": "https://moodle.ecole.fr",
"aud": "formacampus-studio-client-id",
"sub": "u-2342",
"exp": 1893456000,
"iat": 1893455940,
"nonce": "nc-71b3",
"name": "Camille Martin",
"email": "camille.martin@ecole.fr",
"https://purl.imsglobal.org/spec/lti/claim/message_type": "LtiResourceLinkRequest",
"https://purl.imsglobal.org/spec/lti/claim/version": "1.3.0",
"https://purl.imsglobal.org/spec/lti/claim/deployment_id": "dep-1",
"https://purl.imsglobal.org/spec/lti/claim/roles": [
"http://purl.imsglobal.org/vocab/lis/v2/membership#Learner"
],
"https://purl.imsglobal.org/spec/lti/claim/context": {
"id": "course-9271",
"label": "MATH-6A",
"title": "Mathematiques 6e A",
"type": ["http://purl.imsglobal.org/vocab/lis/v2/course#CourseSection"]
},
"https://purl.imsglobal.org/spec/lti/claim/resource_link": {
"id": "res-4815",
"title": "Entrainement calcul mental"
},
"https://purl.imsglobal.org/spec/lti/claim/launch_presentation": {
"document_target": "iframe",
"return_url": "https://moodle.ecole.fr/mod/lti/return.php",
"locale": "fr"
},
"https://purl.imsglobal.org/spec/lti/claim/custom": {
"niveau": "6e",
"chapitre": "fractions"
}
}Décryptage des claims que tu utiliseras le plus :
Claim (suffixe après .../claim/) | Ce qu’il dit |
|---|---|
message_type | Le type de lancement : LtiResourceLinkRequest (lancement normal) ou LtiDeepLinkingRequest (choix de contenu, Partie 10). |
roles | Les rôles de l’utilisateur dans ce contexte, en URIs (...#Learner, ...#Instructor, ...#ContentDeveloper…). |
context | Le cours : id, label, title, type. |
resource_link | L’activité précise d’où part le lancement (id stable — utile pour lier tes données). |
launch_presentation | Le cadre d’affichage (iframe ou fenêtre), l’URL de retour vers le LMS, la locale. |
custom | Les paramètres personnalisés définis à la configuration (ex. niveau, chapitre). |
deployment_id | Le déploiement (à recouper avec ta config). |
Et les claims standard OIDC (hors namespace LTI) : sub (identité de l’utilisateur chez la plateforme), iss, aud, exp, nonce, et — si la plateforme les partage — name, email, given_name, family_name.
⚠️ Piège — Traiter
subcomme un e-mail ou un nom.subest un identifiant opaque et stable de l’utilisateur pour cette plateforme : c’est lui (couplé auiss) que tu utilises comme clé pour relier tes données à un apprenant, pas l’e-mail (qui peut changer, être absent, ou ne pas être partagé). De plus,name/
🔒 Ne demande et ne stocke que les données nécessaires : un lancement LTI peut transporter nom et e-mail, mais s’ils ne te servent pas, ne les conserve pas. Cette discipline relève du RGPD — ton outil, branché dans des LMS d’écoles, traite des données de mineurs.
Lire les rôles correctement
Les rôles arrivent comme un tableau d’URIs. Les plus courants :
"https://purl.imsglobal.org/spec/lti/claim/roles": [
"http://purl.imsglobal.org/vocab/lis/v2/membership#Instructor"
]...membership#Learner: apprenant....membership#Instructor: enseignant/formateur....membership#ContentDeveloper,...membership#Mentor,...membership#TeachingAssistant: autres rôles de contexte.- Il existe aussi des rôles institution et système (préfixes différents) — pour la plupart des outils, seuls les rôles de contexte (
membership#…) importent.
Un utilisateur peut avoir plusieurs rôles. Vérifie la présence d’un rôle dans le tableau (par exemple « est-il Instructor ? ») plutôt que d’attendre une valeur unique.
🧭 Sur FormaCampus — À l’enregistrement avec une école, le studio FormaCampus fournit son URL de login, ses
redirect_uriet sonjwks_uri; il reçoit l’issdu Moodle, sonclient_id, l’endpoint d’auth, le token endpoint et lejwks_uride l’école. Au lancement, le studio litroles: si#Instructor, il affiche le tableau de bord enseignant (voir les scores de la classe) ; si#Learner, l’interface d’exercices. Il utilisesub+isscomme clé d’élève, litcontext.idpour rattacher au bon cours, etcustom.chapitrepour ouvrir directement le bon module. Le tout après validation du jeton.
📚 La spec — Les claims LTI sont définis par LTI 1.3 Core (1EdTech), namespacés sous
https://purl.imsglobal.org/spec/lti/claim/. Les rôles suivent le vocabulaire LIS (http://purl.imsglobal.org/vocab/lis/v2/…). L’enregistrement dynamique suit le profil LTI Dynamic Registration. Les claims de services (AGS, NRPS) ont leurs propres namespaces (.../spec/lti-ags/…,.../spec/lti-nrps/…) — on les lit en Partie 10.
✏️ Exercices
Exercice 1 — Qui voit quoi ? Ton outil reçoit un lancement validé avec roles contenant ...membership#Instructor et un context.id = "course-9271". Que dois-tu afficher, et quelle donnée utilises-tu comme identifiant d’utilisateur stable ?
✅ Solution
Rôle enseignant → afficher l’interface enseignant (par exemple le suivi de la classe), pas l’interface élève. Comme identifiant stable de l’utilisateur, utiliser sub (couplé à l’iss de la plateforme), pas l’e-mail ni le nom (facultatifs, changeants, parfois non partagés). Le context.id (course-9271) sert à rattacher l’affichage au bon cours.
Exercice 2 — Enregistrement. Un administrateur d’académie doit brancher ton outil dans son Moodle mais se plaint que « la doc a douze étapes et il se trompe sur les URLs ». Que proposes-tu, et quel bénéfice concret ?
✅ Solution
Proposer le Dynamic Registration : l’admin colle une seule URL de ton outil dans Moodle, et les deux systèmes s’échangent automatiquement client_id, endpoints et jwks_uri. Bénéfice : moins d’erreurs (fini les redirect_uri mal recopiées, cause classique d’échec au temps 2 du lancement), moins de support, adoption plus rapide. C’est un argument d’intégration et de vente.
🧠 Quiz de révision
1. Qu’échange-t-on à l’enregistrement LTI 1.3 ?
L’outil fournit son URL de login, ses redirect_uri et son jwks_uri ; la plateforme fournit son iss, le client_id, ses endpoints (auth, token), son jwks_uri et le deployment_id. Chacun range les coordonnées de l’autre.
2. Différence entre client_id et deployment_id ?
client_id et deployment_id ?client_id identifie l’outil auprès de la plateforme (l’application). deployment_id identifie une instance de déploiement de cet outil dans la plateforme : même client_id, plusieurs deployment_id possibles.
3. Où sont les claims LTI dans le id_token, et comment les reconnaître ?
id_token, et comment les reconnaître ?Dans le payload du JWT, namespacés sous https://purl.imsglobal.org/spec/lti/claim/ (ex. .../claim/roles, .../claim/context). Les claims OIDC standard (sub, iss, aud, exp, nonce) sont hors namespace.
4. Pourquoi utiliser sub plutôt que l’e-mail comme identifiant ?
sub plutôt que l’e-mail comme identifiant ?sub est un identifiant opaque et stable de l’utilisateur pour la plateforme (à coupler au iss). L’e-mail peut changer, être absent, ou ne pas être partagé selon les réglages de confidentialité. sub est la clé fiable.
5. Que permet le Dynamic Registration ?
D’automatiser l’échange des paramètres d’enregistrement : l’admin de la plateforme fournit une seule URL de l’outil, et les deux systèmes se configurent mutuellement. Moins d’erreurs, moins de support, adoption plus rapide.
Fin de la Partie 9. Le socle LTI 1.3 est posé ; place à ce qui crée la vraie valeur : Partie 10 — LTI Advantage — Deep Linking, renvoi de notes (AGS) et lecture de roster (NRPS).