JSON Web Token ( JWT , prononciation suggérée / dʒ ɒ t / , identique au mot « jot » ) est une norme Internet proposée pour la création de données avec une signature facultative et/ou un cryptage facultatif dont la charge utile contient du JSON qui affirme un certain nombre de revendications . Les jetons sont signés soit à l'aide d'un secret privé , soit d'une clé publique/privée .
Par exemple, un serveur peut générer un jeton qui a la revendication « connecté en tant qu'administrateur » et le fournir à un client. Le client peut ensuite utiliser ce jeton pour prouver qu'il est connecté en tant qu'administrateur. Les jetons peuvent être signés par la clé privée d'une partie (généralement celle du serveur) afin que n'importe quelle partie puisse ensuite vérifier si le jeton est légitime. Si l'autre partie, par un moyen approprié et fiable, est en possession de la clé publique correspondante, elle est également en mesure de vérifier la légitimité du jeton. Les jetons sont conçus pour être compacts, sécurisés par URL , et utilisables, en particulier dans un contexte d'authentification unique (SSO) par navigateur Web . Les revendications JWT peuvent généralement être utilisées pour transmettre l'identité des utilisateurs authentifiés entre un fournisseur d'identité et un fournisseur de services , ou tout autre type de revendications requis par les processus métier.
JWT s'appuie sur d'autres normes basées sur JSON : JSON Web Signature et JSON Web Encryption .
Structure
- En-tête
- Identifie l'algorithme utilisé pour générer la signature. Dans l'exemple ci-dessous,
HS256indique que ce jeton est signé à l'aide de HMAC-SHA256.
- Les algorithmes cryptographiques typiques utilisés sont HMAC avec SHA-256 (HS256) et la signature RSA avec SHA-256 (RS256). JWA (JSON Web Algorithms) RFC 7518 en introduit beaucoup d'autres pour l'authentification et le cryptage.
{ "alg" : "HS256" , "typ" : "JWT" }
- Charge utile
- Contient un ensemble de revendications. La spécification JWT définit sept noms de revendications enregistrés, qui sont les champs standard généralement inclus dans les jetons. Des revendications personnalisées sont généralement également incluses, en fonction de l'objectif du jeton.
- Cet exemple comporte la revendication standard Issued At Time (
iat) et une revendication personnalisée (loggedInAs). { "loggedInAs" : "admin" , "iat" : 1422779638 }
- Signature
- Valide le jeton de manière sécurisée. La signature est calculée en codant l'en-tête et la charge utile à l'aide du codage Base64url RFC 4648 et en concaténant les deux avec un séparateur de points. Cette chaîne est ensuite exécutée via l'algorithme cryptographique spécifié dans l'en-tête. Cet exemple utilise HMAC-SHA256 avec un secret partagé (des algorithmes de clé publique sont également définis). Le codage Base64url est similaire à base64 , mais utilise des caractères non alphanumériques différents et omet le remplissage.
HMAC_SHA256 ( secret , base64urlEncoding ( en-tête ) + '.' + base64urlEncoding ( charge utile ) )
Les trois parties sont codées séparément à l'aide du codage Base64url RFC 4648 et concaténées à l'aide de points pour produire le JWT :
const token = base64urlEncoding ( en-tête ) + '.' + base64urlEncoding ( charge utile ) + '.' + base64urlEncoding ( signature )
Les données ci-dessus et le secret de « secretkey » créent le jeton :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN _oWnFSRgCzcmJmMjLiuyu5CSpyHI=
(Les chaînes json ci-dessus sont formatées sans sauts de ligne ni espaces, dans des tableaux d'octets utf-8. Ceci est important car même de légères modifications dans les données affecteront le jeton résultant)
Ce jeton résultant peut être facilement transmis en HTML et HTTP .
Utiliser
Lors de l'authentification, lorsqu'un utilisateur se connecte avec succès, un jeton Web JSON (JWT) est souvent renvoyé. Ce jeton doit être envoyé au client à l'aide d'un mécanisme sécurisé comme un cookie HTTP uniquement . Le stockage local du JWT dans des mécanismes de stockage de navigateur tels que le stockage local ou de session est déconseillé. En effet, JavaScript exécuté côté client (y compris les extensions de navigateur) peut accéder à ces mécanismes de stockage, exposant le JWT et compromettant la sécurité. Pour les processus sans surveillance, le client peut également s'authentifier directement en générant et en signant son propre JWT avec un secret pré-partagé et en le transmettant à un service compatible OAuth comme suit :
POST /oauth2/token Type de contenu : application / x-www-form-urlencoded grant_type = urn:ietf:params:oauth:grant-type:jwt-bearer & assertion = eyJhb...
Si le client transmet une assertion JWT valide, le serveur générera un access_token valide pour effectuer des appels à l'application et le renverra au client :
{ "access_token" : "eyJhb..." , "token_type" : "Porteur" , "expires_in" : 3600 }
Lorsque le client souhaite accéder à une route ou à une ressource protégée, l'agent utilisateur doit envoyer le JWT, généralement dans l' Authorization
en-tête HTTP à l'aide du Bearerschéma. Le contenu de l'en-tête peut ressembler à ce qui suit :
Autorisation : Porteur eyJhbGci ...<snip>... yu5CSpyHI
Il s'agit d'un mécanisme d'authentification sans état, car l'état de l'utilisateur n'est jamais enregistré dans la mémoire du serveur. Les routes protégées du serveur vérifient la présence d'un JWT valide dans l'en-tête d'autorisation et, s'il est présent, l'utilisateur est autorisé à accéder aux ressources protégées. Les JWT étant autonomes, toutes les informations nécessaires sont présentes, ce qui réduit la nécessité d'interroger la base de données plusieurs fois.
Champs standards
La liste des noms de revendications actuellement enregistrés peut être obtenue auprès du registre des revendications de jetons Web JSON de l'IANA .
Implémentations
Des implémentations JWT existent pour de nombreux langages et frameworks, notamment, mais sans s'y limiter :
Vulnérabilités
Les jetons Web JSON peuvent contenir l'état de la session. Mais si les exigences du projet permettent l'invalidation de la session avant l'expiration du JWT, les services ne peuvent plus faire confiance aux assertions du jeton par le jeton seul. Pour valider que la session stockée dans le jeton n'est pas révoquée, les assertions du jeton doivent être vérifiées par rapport à un magasin de données . Cela rend les jetons non plus sans état, ce qui compromet l'avantage principal des JWT.
Le consultant en sécurité Tim McLean a signalé des vulnérabilités dans certaines bibliothèques JWT qui utilisaient le algchamp pour valider de manière incorrecte des jetons, le plus souvent en acceptant un alg=nonejeton. Bien que ces vulnérabilités aient été corrigées, McLean a suggéré de déprécier algcomplètement le champ pour éviter une confusion d'implémentation similaire. Pourtant, de nouvelles alg=nonevulnérabilités sont toujours découvertes dans la nature, avec quatre CVE déposés au cours de la période 2018-2021 ayant cette cause.
Avec une conception appropriée, les développeurs peuvent remédier aux vulnérabilités des algorithmes en prenant des précautions :
- Ne laissez jamais l'en-tête JWT seul piloter la vérification
- Connaître les algorithmes (éviter de dépendre uniquement du
algdomaine) - Utilisez une taille de clé appropriée
Plusieurs bibliothèques JWT se sont révélées vulnérables à une attaque par courbe elliptique non valide en 2017.
Certains ont fait valoir que les jetons Web JSON sont difficiles à utiliser en toute sécurité en raison des nombreux algorithmes et options de cryptage différents disponibles dans la norme, et que des normes alternatives devraient plutôt être utilisées pour les interfaces Web et les back-ends.