4. DPoP Proof JWTs
4. DPoP Proof JWTs
DPoP introduit le concept de preuve DPoP (DPoP proof), qui est un JWT créé par le client et envoyé avec une requête HTTP à l'aide du champ d'en-tête DPoP. Chaque requête HTTP nécessite une preuve DPoP unique.
Une preuve DPoP valide démontre au serveur que le client détient la clé privée qui a été utilisée pour signer le JWT de preuve DPoP. Cela permet aux serveurs d'autorisation de lier les jetons émis à la clé publique correspondante (comme décrit dans la section 5) et permet aux serveurs de ressources de vérifier la liaison de clé des jetons qu'ils reçoivent (voir la section 7.1), ce qui empêche lesdits jetons d'être utilisés par toute entité qui n'a pas accès à la clé privée.
Une preuve DPoP démontre la possession d'une clé et n'est pas, en soi, un mécanisme d'authentification ou de contrôle d'accès. Lorsqu'elle est présentée en combinaison avec un jeton d'accès lié à une clé, comme décrit dans la section 7.1, une preuve DPoP fournit une assurance supplémentaire concernant la légitimité du client présentant le jeton d'accès. Cependant, un JWT de preuve DPoP valide n'est en aucun cas suffisant à lui seul pour prendre des décisions de contrôle d'accès.
4.1. L'en-tête HTTP DPoP
Une preuve DPoP est incluse dans une requête HTTP à l'aide du champ d'en-tête de requête suivant :
DPoP : Un JWT conforme à la structure et à la syntaxe de la section 4.2.
La Figure 2 montre un exemple de champ d'en-tête HTTP DPoP. L'exemple utilise "\" pour le retour à la ligne, conformément à la [RFC8792].
DPoP: eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6Ik\
VDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCR\
nMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JE\
QSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIj\
oiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwia\
WF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg\
4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg
Figure 2: Exemple d'en-tête DPoP
Notez que selon la [RFC9110], les noms de champs d'en-tête sont insensibles à la casse ; ainsi, DPoP, DPOP et dpop sont tous des noms de champs d'en-tête valides et équivalents. Cependant, la casse de la valeur du champ d'en-tête est significative.
La valeur du champ d'en-tête HTTP DPoP utilise la syntaxe token68 définie dans la section 11.2 de la [RFC9110]. Par commodité, elle est reproduite dans la Figure 3.
DPoP = token68
token68 = 1*( ALPHA / DIGIT /
"-" / "." / "_" / "~" / "+" / "/" ) *"="
Figure 3: ABNF du champ d'en-tête DPoP
4.2. Syntaxe du JWT de preuve DPoP
Une preuve DPoP est un JWT [RFC7519] qui est signé (à l'aide de JSON Web Signature (JWS) [RFC7515]) avec une clé privée choisie par le client (voir ci-dessous). L'en-tête JOSE d'un JWT DPoP DOIT contenir au moins les paramètres suivants :
typ : Un champ portant la valeur dpop+jwt, qui type explicitement le JWT de preuve DPoP comme recommandé dans la section 3.11 de la [RFC8725].
alg : Un identifiant d'algorithme de signature numérique asymétrique JWS provenant de [IANA.JOSE.ALGS]. Il NE DOIT PAS être none ou un identifiant pour un algorithme symétrique (Message Authentication Code (MAC)).
jwk : La clé publique choisie par le client, au format JSON Web Key (JWK) [RFC7517], tel que défini dans la section 4.1.3 de la [RFC7515]. Elle NE DOIT PAS contenir la clé privée.
La charge utile d'une preuve DPoP DOIT contenir au moins les revendications suivantes :
jti : Identifiant unique pour le JWT de preuve DPoP. La valeur DOIT être assignée de telle sorte que la probabilité que la même valeur soit assignée à toute autre preuve DPoP utilisée dans le même contexte pendant la période de validité de la preuve soit négligeable. Une telle unicité peut être obtenue en encodant (base64url ou tout autre encodage approprié) au moins 96 bits de données pseudo-aléatoires ou en utilisant une chaîne d'identifiant unique universel (UUID) de version 4 selon la [RFC4122]. La revendication jti peut être utilisée par le serveur pour la détection et la prévention du rejeu (voir la section 11.1).
htm : La valeur de la méthode HTTP ([RFC9110], section 9.1) de la requête à laquelle le JWT est attaché.
htu : La valeur de l'URI HTTP ([RFC9110], section 7.1) de la requête à laquelle le JWT est attaché, sans les parties requête (query) et fragment.
iat : Horodatage de création du JWT ([RFC7519], section 4.1.6).
Lorsqu'une preuve DPoP est utilisée en conjonction avec un jeton d'accès pour accéder à une ressource protégée (voir la section 7), la preuve DPoP DOIT également contenir la revendication suivante :
ath : Hachage du jeton d'accès. La valeur DOIT être le résultat d'un codage base64url (tel que défini dans la section 2 de la [RFC7515]) du hachage SHA-256 [SHS] du codage ASCII de la valeur du jeton d'accès associé.
Lorsque le serveur d'autorisation ou le serveur de ressources fournit un nonce via l'en-tête HTTP DPoP-Nonce (voir les sections 8 et 9), la preuve DPoP DOIT également contenir la revendication suivante :
nonce : Un nonce récent fourni via l'en-tête HTTP DPoP-Nonce.
Une preuve DPoP PEUT contenir d'autres paramètres d'en-tête JOSE ou revendications selon les extensions, les profils ou les exigences spécifiques au déploiement.
La Figure 4 montre un exemple conceptuel du contenu décodé de la preuve DPoP de la Figure 2. Le JSON de l'en-tête JWT et de la charge utile est affiché, mais la partie signature est omise. Comme d'habitude, des sauts de ligne et des espaces supplémentaires sont inclus pour le formatage et la lisibilité.
{
"typ":"dpop+jwt",
"alg":"ES256",
"jwk": {
"kty":"EC",
"x":"l8tFrhx-34tV3hRICRDY9zCkDlpBhF42UQUfWVAWBFs",
"y":"9VE4jf_Ok_o64zbTTlcuNJajHmt6v9TDVrU0CdvGRDA",
"crv":"P-256"
}
}
.
{
"jti":"-BwC3ESc6acc2lTc",
"htm":"POST",
"htu":"https://server.example.com/token",
"iat":1562262616
}
Figure 4: Exemple de contenu JWT de preuve DPoP
De la requête HTTP, seules la méthode HTTP et l'URI sont incluses dans le JWT DPoP, et donc la preuve DPoP ne couvre que ces deux parties du message. L'idée est de ne signer que suffisamment de données HTTP pour fournir une preuve de possession raisonnabl pour la requête HTTP. Cette approche de conception consistant à n'utiliser qu'un sous-ensemble minimal de données d'en-tête HTTP permet d'éviter les difficultés importantes inhérentes à toute tentative de canonicalisation (normalisation) des messages HTTP. Néanmoins, les preuves DPoP peuvent être étendues pour contenir d'autres informations de la requête HTTP (voir aussi la section 11.7).
4.3. Vérification des preuves DPoP
Pour valider une preuve DPoP, le serveur destinataire DOIT s'assurer que :
- Il n'y a qu'un seul champ d'en-tête de requête HTTP DPoP.
- La valeur du champ d'en-tête de requête HTTP DPoP est un JWT unique et bien formé.
- Toutes les revendications requises listées dans la section 4.2 sont contenues dans le JWT.
- La valeur du paramètre d'en-tête typ JOSE est dpop+jwt.
- Le paramètre d'en-tête alg JOSE indique un algorithme de signature numérique asymétrique enregistré [IANA.JOSE.ALGS], n'est pas none, est pris en charge par l'application et est acceptable selon la politique locale.
- La signature JWT est validée à l'aide de la clé publique contenue dans le paramètre d'en-tête jwk JOSE.
- Le paramètre d'en-tête jwk JOSE ne contient pas de clé privée.
- La revendication htm correspond à la méthode HTTP de la requête actuelle.
- La revendication htu correspond à la valeur de l'URI HTTP de la requête HTTP dans laquelle le JWT a été reçu, en ignorant les parties requête et fragment.
- Si le serveur a fourni une valeur de nonce au client, la revendication nonce correspond à la valeur de nonce fournie par le serveur.
- L'heure de création du JWT, déterminée par la revendication iat ou l'horodatage géré par le serveur via la revendication nonce, se situe dans une fenêtre de temps acceptable (voir la section 11.1).
- Lorsqu'il est présenté à une ressource protégée en conjonction avec un jeton d'accès :
- la valeur de la revendication ath est égale au hachage de ce jeton d'accès, et
- s'assurer que la clé publique à laquelle le jeton d'accès est lié correspond à la clé publique de la preuve DPoP.
Pour réduire le risque de faux positifs, les serveurs DEVRAIENT (SHOULD) employer la normalisation basée sur la syntaxe ([RFC3986], section 6.2.2) et la normalisation basée sur le schéma ([RFC3986], section 6.2.3) avant de comparer la revendication htu.
Ces vérifications peuvent être effectuées dans n'importe quel ordre.