Qu'est-ce qu'un JSON Web Token (JWT) ?
Un format de jeton compact, signé et lisible en JSON : comment il est construit, comment le vérifier et pourquoi il porte la plupart des jetons de l'identité moderne.
- Nom complet
- JSON Web Token
- Publié par
- IETF, 2015
- Repose sur
- JWS, JWE, JWK et JWA (RFC 7515 à 7518)
- Dans TOSIAM
- ID tokens, access tokens JWT, assertions des clients
Sur cette page
Les JWT en bref#
Un JSON Web Token (JWT, prononcé « jot ») est un jeton compact qui transporte des informations sous forme d’objet JSON, protégées par une signature ou par un chiffrement. Celui qui le reçoit peut vérifier qui l’a émis et s’assurer que son contenu n’a pas été modifié, sans interroger l’émetteur.
Le format est défini par la RFC 7519, publiée par l’IETF en 2015. Il ne décrit pas un protocole, mais un conteneur : ce sont d’autres normes qui disent quoi y mettre et quand l’utiliser. L’ID token d’OpenID Connect, de nombreux access tokens OAuth 2.0 et les assertions qui servent à authentifier un client sont des JWT.
Pourquoi les JWT existent#
Un jeton classique est une référence opaque : une chaîne aléatoire qui ne veut rien dire en elle-même. Pour savoir à qui elle appartient et ce qu’elle autorise, le destinataire doit interroger le serveur qui l’a émise, à chaque requête.
Un JWT est autoporteur : il contient lui-même les informations utiles (l’émetteur, l’utilisateur, la date d’expiration, les droits accordés), et sa signature prouve qu’elles viennent bien de l’émetteur. Une API peut donc le valider seule, avec la clé publique de l’émetteur.
Le format a été pensé pour le web : il tient sur une seule ligne, ne contient que des caractères autorisés dans une URL ou un en-tête HTTP, et se lit avec n’importe quelle bibliothèque JSON.
Anatomie d’un JWT#
Un JWT signé se compose de trois parties encodées en Base64url et séparées par des points : l’en-tête, le contenu (payload) et la signature.
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InJzYS0yMDI2In0.eyJpc3MiOiJodHRwczovL2xvZ2luLmV4YW1wbGUuZnIvdG9zaWFtL29hdXRoMiIsInN1YiI6ImNsYWlyZS5tYXJ0aW4ifQ.kLp3Q9vZ2mT8wXe1R4yN6bUcH0sJfA7dGiO5qVtMx2EwDécodées, les deux premières parties sont de simples objets JSON :
{
"alg": "RS256",
"typ": "JWT",
"kid": "rsa-2026"
}{
"iss": "https://login.example.fr/tosiam/oauth2",
"sub": "claire.martin"
}- L’en-tête indique comment le jeton est protégé : l’algorithme (
alg), le type de jeton (typ) et l’identifiant de la clé utilisée (kid). - Le contenu porte les claims, c’est-à-dire les affirmations de l’émetteur.
- La signature est calculée sur les deux premières parties. Modifier un seul caractère de l’en-tête ou du contenu la rend invalide.
Les claims enregistrés#
La RFC 7519 définit quelques claims standard, tous facultatifs, que les autres normes reprennent :
| Claim | Signification |
|---|---|
iss | L’émetteur du jeton (issuer). |
sub | Le sujet : l’utilisateur ou le client que le jeton décrit. |
aud | Le ou les destinataires prévus (audience). Un destinataire qui ne s’y reconnaît pas doit refuser le jeton. |
exp | La date d’expiration, en secondes depuis 1970. |
nbf | La date avant laquelle le jeton n’est pas encore valable (not before). |
iat | La date d’émission (issued at). |
jti | Un identifiant unique, qui permet de détecter un rejeu ou de révoquer ce jeton précis. |
À ces claims s’ajoutent ceux définis par chaque usage : nonce et auth_time pour un ID token, scope et client_id pour un access token, ou des claims propres à une organisation.
Signer ou chiffrer : JWS et JWE#
Un JWT est presque toujours signé, au format JWS (RFC 7515). Il peut aussi être chiffré, au format JWE (RFC 7516) : il compte alors cinq parties au lieu de trois, et seul le détenteur de la clé de déchiffrement peut lire son contenu. Pour obtenir les deux garanties, on signe d’abord, puis on chiffre le jeton signé.
Les algorithmes de signature, définis dans la RFC 7518, se répartissent en deux familles :
| Famille | Exemples | Clé | Qui peut vérifier ? |
|---|---|---|---|
| HMAC | HS256, HS384, HS512 | Un secret partagé | Seulement ceux qui connaissent le secret, et qui pourraient donc aussi fabriquer des jetons. |
| Asymétrique | RS256, PS256, ES256, EdDSA | Une paire de clés | Tout le monde, avec la clé publique ; seul l’émetteur détient la clé privée. |
| Aucune | none | Aucune | Personne : le jeton n’est pas protégé. |
Dès qu’un jeton doit être vérifié par plusieurs services, un algorithme asymétrique s’impose : l’émetteur garde sa clé privée, et publie sa clé publique.
Vérifier un JWT#
Les clés publiques d’un émetteur sont publiées au format JWK (RFC 7517), regroupées dans un JWKS (JSON Web Key Set) accessible à une adresse fixe. Chaque clé porte un kid, que l’en-tête du jeton reprend pour désigner la clé à utiliser :
{
"keys": [
{
"kty": "RSA",
"kid": "rsa-2026",
"use": "sig",
"alg": "RS256",
"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc…",
"e": "AQAB"
}
]
}Le parcours complet, de l’émission à la vérification, ressemble à ceci :
- Application vers TOSIAM Demande un jeton sur l’endpoint de jeton
- TOSIAM Construit les claims et les signe avec sa clé privée
- TOSIAM vers Application Renvoie le JWT
-
Application vers API
Appelle l’API avec
Authorization: Bearer <jwt> - API vers TOSIAM Télécharge le JWKS, s’il n’est pas déjà en cache
-
API
Retrouve la clé par son
kidet vérifie la signature -
API
Contrôle
iss,aud,exp, puis les droits - API vers Application Répond à la requête
Dans l’ordre, le destinataire :
- vérifie que l’algorithme de l’en-tête fait partie de ceux qu’il accepte pour cet émetteur ;
- vérifie la signature avec la bonne clé ;
- contrôle l’émetteur (
iss), l’audience (aud) et les dates (exp,nbf), avec une faible tolérance d’horloge ; - seulement ensuite, lit les autres claims pour prendre sa décision.
À quoi servent les JWT#
| Usage | Norme | Rôle du JWT |
|---|---|---|
| ID token | OpenID Connect Core | Décrire une authentification à l’application. |
| Access token au format JWT | RFC 9068 | Porter les droits accordés, pour une API qui le valide elle-même. En-tête typ : at+jwt. |
| Authentification d’un client | RFC 7523, méthode private_key_jwt | Prouver l’identité d’une application par une assertion signée de sa clé privée, à la place d’un secret. |
| Grant type JWT Bearer | RFC 7523 | Échanger une assertion signée contre un access token. |
| Requête d’autorisation signée | RFC 9101 | Protéger les paramètres d’une demande d’autorisation, souvent avec PAR. |
Les limites#
Le principal atout du JWT, être vérifiable sans l’émetteur, est aussi sa principale limite : un JWT valide le reste jusqu’à son expiration. Si un utilisateur se déconnecte ou si un jeton est volé, les services qui ne font que vérifier la signature continueront à l’accepter. D’où l’usage de durées de vie courtes, de quelques minutes à une heure, complétées par des refresh tokens.
Un JWT est aussi plus volumineux qu’une référence opaque (plusieurs centaines d’octets, parfois quelques kilo-octets), et son contenu est lisible par quiconque l’intercepte.
Bonnes pratiques#
La RFC 8725 rassemble les bonnes pratiques actuelles :
- Fixez la liste des algorithmes acceptés côté destinataire, au lieu de faire confiance au champ
algdu jeton. Refusez toujoursnone. - Ne mélangez jamais les familles pour une même clé : une bibliothèque qui accepte
HS256là où elle attendRS256peut être trompée avec la clé publique utilisée comme secret HMAC. - Vérifiez systématiquement
iss,audetexp. Un jeton émis pour une autre application ne doit pas être accepté par la vôtre. - Distinguez les types de jetons par le champ
typou par des claims dédiés, pour qu’un ID token ne soit jamais accepté comme access token. - Récupérez les clés depuis le JWKS de l’émetteur et gardez-les en cache ; rechargez-le quand un
kidinconnu apparaît, ce qui arrive après une rotation de clés. - Gardez des durées de vie courtes et ne stockez dans le jeton que ce dont le destinataire a besoin.
- Transmettez les JWT uniquement sur HTTPS : un jeton bearer vaut pour quiconque le présente.
Les JWT dans TOSIAM#
TOSIAM émet des JWT en tant que fournisseur OAuth 2.0 et OpenID Connect, et en accepte de la part des applications clientes.
Les clés publiques. Le fournisseur publie son JWKS à l’adresse /connect/jwk_uri sous son émetteur, par exemple https://login.example.fr/tosiam/oauth2/clients/connect/jwk_uri pour le royaume clients. Le JWKS contient les clés publiques RSA et EC du fournisseur, chacune identifiée par un kid.
Les ID tokens. L’algorithme de signature se choisit sur chaque agent OAuth 2.0, parmi ceux que le fournisseur annonce : HS256 à HS512, RS256 à RS512 et ES256 à ES512. La valeur par défaut d’un agent est HS256, qui signe avec le secret du client : seul ce client peut alors vérifier le jeton. Avec RS256 ou ES256, n’importe quel destinataire peut le vérifier grâce au JWKS. Un agent peut aussi demander que ses ID tokens soient chiffrés (JWE).
Les access tokens. Par défaut, TOSIAM délivre des access tokens opaques, dont le contenu est conservé dans le Core Token Store (CTS). Deux options produisent des JWT :
- « Émettre les jetons d’accès sous forme de JWT », sur l’agent : le jeton reste enregistré dans le CTS, mais il est remis sous forme d’un JWT d’en-tête
typ: at+jwt, conforme à la RFC 9068, dont lejtiest l’identifiant CTS. Il contient notammentiss,sub,aud(l’identifiant du client),client_id,scope,iat,expetauth_time. Cette option exige un algorithme asymétrique (RS ou ES) dans le réglage « Algorithme de signature des jetons OAuth2 » du fournisseur : la valeur par défaut, HS256, est refusée pour ces jetons. - Les jetons sans état (stateless), à activer à la fois dans le service OAuth2 Provider du royaume et sur l’agent : le JWT est lui-même le jeton, access comme refresh. TOSIAM enregistre tout de même leurs métadonnées dans le CTS, et la révocation passe par une liste noire, elle aussi conservée dans le CTS, qu’il consulte quand il valide un jeton. Une API qui ne fait que vérifier la signature n’a pas connaissance de cette liste.
Un script défini sur le fournisseur peut modifier les access tokens au moment de leur émission. La page Tokens compare les jetons stockés dans le CTS et les jetons sans état.
Les JWT reçus des clients. Une application peut s’authentifier auprès de TOSIAM par la méthode private_key_jwt : elle signe une assertion avec sa clé privée, et TOSIAM la vérifie avec la clé publique déclarée sur l’agent, fournie par une adresse JWKS (le choix par défaut), un JWKS recopié dans l’agent ou un certificat X.509. TOSIAM accepte aussi le grant type urn:ietf:params:oauth:grant-type:jwt-bearer : l’iss de l’assertion doit être l’identifiant d’un agent autorisé à utiliser ce grant type, les claims sub, aud et exp sont obligatoires, l’audience doit contenir l’endpoint de jeton, et les assertions non signées (none) ou signées par secret partagé (HS) sont refusées.
Pour aller plus loin#
- RFC 7519 : JSON Web Token (JWT)
- RFC 7515 : JSON Web Signature (JWS) et RFC 7516 : JSON Web Encryption (JWE)
- RFC 7517 : JSON Web Key (JWK) et RFC 7518 : JSON Web Algorithms (JWA)
- RFC 8725 : JSON Web Token Best Current Practices
- RFC 9068 : JWT Profile for OAuth 2.0 Access Tokens
- RFC 7523 : JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants
Mis à jour le