Accueil > OpenID Connect OAuth Server par DnC > Développer > JSON Web Token (JWT)

JSON Web Token (JWT)

JWT est un standard ouvert (RFC 7519) qui définit une manière compacte et autonome de transmission sécurisée d’informations entre les parties sous la forme d’un objet JSON.

Les documents suivants spécifient comment le jeton JWT est mis en oeuvre :
- pour OAuth 2.0 : RFC 7523 : JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
- pour OpenID Connect : OpenID Connect Core 1.0 incorporating errata set 1.

 

Avertissement : OpenID Connect fait un usage particulier de JWT pour élaborer le jeton d’identité. Voyez : OpenID Connect : le jeton d’identité ( ID Token ) JWT.

Structure du Jeton JWT

Un jeton JWT se compose de trois parties séparées par des points (.) :

<header>.<payload>.<signature>

Chacune de ces trois composantes est codé Base64Url. OAuth 2.0 Server PHP utilise les fonctions suivantes :

PHP

  1. /**
  2. * @author    Brent Shaffer <bshafs at gmail dot com>
  3.  * @license   MIT License
  4. */
  5.  
  6.     public function urlSafeB64Encode($data)
  7.     {
  8.         $b64 = base64_encode($data);
  9.         $b64 = str_replace(array('+', '/', "\r", "\n", '='),
  10.                 array('-', '_'),
  11.                 $b64);
  12.  
  13.         return $b64;
  14.     }
  15.  
  16.     public function urlSafeB64Decode($b64)
  17.     {
  18.         $b64 = str_replace(array('-', '_'),
  19.                 array('+', '/'),
  20.                 $b64);
  21.  
  22.         return base64_decode($b64);
  23.     }

Télécharger

Bien que son format compact incite à le transmettre par URL, il est recommandé de le transmettre par Header dans l’en-tête Authorization avec le mécanisme d’authentification Bearer :

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImRlbW8iLCJmdWxsTmFtZSI6

Header : Entête

L’en-tête se compose généralement d’un array JSON de deux membres :

Alg : le type du jeton, qui est donc JWT
Typ : l’algorithme de hachage utilisé, comme HMAC SHA256 ou RSA.

Pour coder/décoder la signature, OAuth Server by DnC utilise par défaut l’algorithme HS256 et peut utiliser HS384 ou HS512 ainsi que RS256, RS384 et RS512.

Par exemple :

{
 "typ": "JWT",
  "alg": "HS256"
}

Paylod : Charge utile

La charge utile contient les déclarations sous le format JSON.

Les déclarations (claims) sont des informations sur une entité (généralement, l’utilisateur) et des métadonnées supplémentaires.

Il existe trois types de déclarations : reserved, public et private.

Déclarations réservées

Ces déclarations sont réservées, en ce sens que leur nom ne doit pas être utilisé par d’autres déclarations qui pourraient être définies dans le cadre d’un protocole ou d’une application particuliers.

Elles sont prédéfinies par le standard JWT (voir Registered Claim Names).

Format des déclarations réservées

Avertissement : les définitions données ici sont celles de l’IETF (RFC 7523), différente de la définition générale donnée par la RFC 7519. La fondation OpenID (openid.net) donne une définition plus complète et différente sur certains points.

Les déclarations réservées propres à JWT sont les suivantes (voir JWT Format and Processing Requirements) :

1. Le jeton JWT DOIT contenir une déclaration "iss" (émetteur) contenant l’identifiant unique de l’entité qui a émis le jeton.

2. Le jeton JWT DOIT contenir une déclaration "sub" (subject) identifiant le Principal qui est le sujet de la JWT. Deux cas doivent être différenciés :

A. Pour Authorization Grant, le sujet identifie généralement un accesseur autorisé pour lequel le jeton d’accès est demandé (c’est-à-dire le propriétaire de la ressource ou un délégué autorisé), mais dans certains cas, ce peut être un identifiant pseudonyme ou une autre valeur indiquant un utilisateur anonyme. [1]

B. Pour Client Authentication [2], le sujet DOIT être le "client_id" du client OAuth.

3. Le jeton JWT DOIT contenir une définition "aud" (audience), audience(s) pour laquelle (ou lesquelles)ce jeton d’identité est destiné. Il DOIT contenir le client_id OAuth 2.0 de la partie de confiance en tant que valeur d’audience. [3]

4. Le jeton JWT DOIT contenir une définition "exp" (expiration time) qui limite la fenêtre de temps pendant laquelle le JWT peut être utilisé.

5. Le JWT PEUT contenir une définition « nbf » (not before) qui identifie l’instant avant lequel le jeton NE DOIT PAS être accepté.

6. Le JWT PEUT contenir une définition "iat" (issued at) qui identifie l’instant auquel le jeton a été délivré.

7. Le jeton JWT PEUT contenir une définition "jti" (JWT ID) qui fournit un identifiant unique pour le jeton. Si c’est le cas, le serveur OAuth Server by DnC s’assure qu’un jeton JWT n’est pas réutilisé pendant sa durée de validité.

Le jeton JWT peut également présenter une déclaration at_hash, voir : Validation du jeton d’accès avec la déclaration at_hash du jeton d’identité.

Déclarations publiques

Elles peuvent être définies à volonté. Mais pour éviter les collisions, leurs noms devraient être choisis dans le IANA JSON Web Token Registry mentionné précédemment ou être définis avec la déclaration d’un espace de noms.

Déclarations privées

Ce sont des déclarations personnalisées créées pour partager des informations entre les parties qui ont prévu de les utiliser.

Exemple de déclarations :

{  
 "iss": "https:\/\/oa.dnc.global",
 "iat":1410255630,
 "exp":1410259230,
 "sub": "a394190a00f2d36b21309036b0b",
 "aud":"_c036b0b6f97a394190a00f2d36b213091938d225"
}

Notes :
- Il doit être bien compris que l’en-tête et la charge utile sont de simples chaînes codées en base64, qui peuvent facilement être déchiffrées et lues. Il ne doit donc pas y figurer de donnée sensible.

Signature

La signature est utilisée pour vérifier que l’expéditeur du jeton JWT est bien celui qu’il prétend être et de veiller à ce que le message n’a pas été modifié en cours de route. Un JWT signé est conforme au standard JWS (JSON Web Signature, RFC 7515).

Le JWT est signé en utilisant un secret (avec l’algorithme HMAC) ou une paire de clés publique/privée en utilisant RSA. C’est cette deuxième solution qui est préférée par OAuthSD (la signature par HMAC est jugée insuffisamment sécurisée).

Lorsque l’application passe le jeton à un serveur de ressource protégée (RS), il est impératif que le serveur de ressource valide le jeton. Le serveur de ressource (RS) qui valide la signature doit être en possession de la clé publique correspondant à la clé privée avec laquelle la signature a été élaborée. Il est également possible, voire avantageux, de faire valider le jeton par le serveur d’authentification (voir : API Open ID Connect : Introspection).

OAuthSD : gestion de la paire de clés publique/privée

A chaque application cliente enregistrée sur le serveur correspond une paire de clés publique/privée.

OAuthSD facilite la création et la gestion des clés de la façon suivante :

- La paire de clés publique/privée est créée automatiquement au moment de l’inscription de l’application cliente sur le serveur OAuthSD.

- L’interface de gestion d’OAuthSD permet à l’auteur-propriétaire de l’application d’éditer ces clés.

- De plus, un script updatekeys.php du core permet de re-générer les clés. Il est recommandé d’appeler ce script par une tâche CRON locale régulièrement, par exemple tous les deux mois.
Ce processus est totalement transparent pour les applications clientes validant la signature du JWT par introspection ou qui interogent le point d’accès Keys pour récupérer la clé publique.

Remarque de sécurité

Notons que la validation du jeton ne suffit pas au serveur de ressource pour s’assurer que l’application qui présente le jeton le détient légitimement et éviter de répondre à une application étrangère. Voir à ce sujet : Vérification de l’origine de la requête reçue par un serveur de ressource.

Notes

[1Cette définition approximative implique que la valeur de "sub" et son interprétation dépendent de l’application.

[2Il s’agit du flux JWT Bearer Authorization Grant.

[3La spécification prévoit : "Il PEUT aussi contenir des identifiants pour d’autres audiences. Dans le cas général, la valeur aud est un tableau de chaînes sensibles à la casse. Dans le cas particulier où il n’y a qu’une audience, la valeur aud PEUT être une chaîne sensible à la casse". La bibliothèque oauth2-server-php réduit "aud" à l’id du client client_id.