Attributs dans les tokens JWT Keycloak
Un JWT (JSON Web Token) est un standard ouvert pour la création de tokens sécurisés et compactés, utilisés principalement pour l'authentification et l'échange sécurisé d'informations entre deux parties. Le token JWT est utilisé dans les microservices pour permettre une authentification sans état (stateless) et pour faciliter la communication entre services.
Comment ajouter un attribut personnalisé à un utilisateur, et comment récupérer cet attribut dans la charge utile du jeton JWT
Ajout d'attributs personnalisés pour l'utilisateur
Ajouter des propriétés personnalisées à un utilisateur dans Keycloak est assez simple. Il suffit de se connecter à Keycloak et d’ajouter un attribut personnalisé pour l'utilisateur. Voici un exemple avec une capture d’écran.
Nouvel attribut ‘uai’ pour l’utilisateur ‘admin’.
Dans un ENT (Environnement Numérique de Travail), le terme UAI désigne l'Identifiant Unique de l'Établissement. Il correspond à un code attribué par le ministère de l'Éducation nationale en France pour identifier de manière unique chaque établissement scolaire, qu'il s'agisse d'écoles primaires, de collèges, de lycées, ou d'établissements d'enseignement supérieur.
Ajout de l'attribut dans la charge utile
Lorsque nous récupérons le jeton JWT en utilisant le flux OAuth, nous incluons le scope “profile”. L’attribut utilisateur “UAI” fait partie de ce scope. Donc, nous devons modifier le scope client “profile” pour y ajouter ce champ.
L'autre possibilité est de créer un scope specifique 'openent'.
Ajouter l'attribut utilisateur au scope du jeton JWT
Un mapper dans Keycloak est une entité qui mappe une propriété spécifique, comme l'email de l'utilisateur ou la liste des groupes auxquels il appartient, à des claims spécifiques dans le jeton d'identité (ID token) et le jeton d'accès (access token). Lorsque vous cliquez sur “By configuration” dans l’écran précédent, vous verrez une liste de mappers prédéfinis. Vous devez sélectionner le mapper “User Attribute”, qui vous permettra de mapper tout attribut utilisateur au jeton.
Mapper l’attribut ‘UAI’ au scope du profile.
Nous avons terminé le mapping de l’attribut “UAI”. Tout futur jeton JWT contiendra l’attribut “UAI” avec sa valeur dans la token. Testons cela. Connectons-nous à l’application via Keycloak.
Les attributs sont sensibles à la casse. Veillez à fournir le nom de l’attribut avec la bonne casse.
En inspectant le jeton d’accès JWT, nous constatons qu’il contient l'UAI.
{
"exp": 1677768576,
"iat": 1677768516,
"auth_time": 1677766996,
"jti": "b7d66a84-0541-41f0-b267-3201be76a0ba",
"iss": "http://localhost:8080/realms/master",
"sub": "6f08e71e-191a-478e-8e22-efd589158d90",
"typ": "Bearer",
"azp": "account",
"session_state": "f686a450-4641-4cb6-9fd2-f234fc0ebb41",
"acr": "0",
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid email profile",
"sid": "f686a450-4641-4cb6-9fd2-f234fc0ebb41",
"email_verified": false,
"uai": "1005001R", /* <---------------- YES ! */
"preferred_username": "admin"
}
Comme nous avons configuré l'attribut "UAI" pour qu'il soit également présent dans le jeton d'identité, nous pouvons inspecter ce dernier pour confirmer qu'il contient également la ville.
{
"exp": 1677768576,
"iat": 1677768516,
"auth_time": 1677766996,
"jti": "243de53d-7893-40be-a742-19244c1f6de5",
"iss": "http://localhost:8080/realms/master",
"aud": "account",
"sub": "6f08e71e-191a-478e-8e22-efd589158d90",
"typ": "ID",
"azp": "account",
"session_state": "f686a450-4641-4cb6-9fd2-f234fc0ebb41",
"at_hash": "tr8JnNIGu8fkMHxjFPSf6Q",
"acr": "0",
"sid": "f686a450-4641-4cb6-9fd2-f234fc0ebb41",
"email_verified": false,
"uai": "1005001R",
"preferred_username": "admin"
}
Cet exemple montre l’ajout de l’attribut ‘UAI’ à une claim sous le scope ‘profile’. De la même manière, il est possible d’ajouter des attributs et des données spécifiques à la charge utile en fonction du scope que le client fournit lors de la demande de jeton.
Exemple de token
{
"exp": 1732106029,
"iat": 1732104229,
"jti": "9a95c838-4bd3-4f86-80c8-6c526e868813",
"iss": "https://id.tech.fr/realms/openent",
"aud": "account",
"sub": "745a52f3-0fd2-467b-84c3-a64a4d197d1b",
"typ": "Bearer",
"azp": "backend-service",
"sid": "088d3817-14e0-4910-aec5-d4e75ec548a2",
"realm_access": {
"roles": [
"default-roles-openent",
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"backend-service": {
"roles": [
"SUPER_ADMIN"
]
},
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "openid email profile",
"email_verified": false,
"preferred_username": "jean"
}