Microsoft.IdentityModel.JsonWebTokens crée et valide des JWT avec JsonWebTokenHandler et un objet TokenValidationParameters ; dans ASP.NET Core, AddJwtBearer y fait passer les requêtes, si bien que ses valeurs par défaut sont celles de la plupart des API .NET. La version 8.23.0 a signé et validé les familles HS, RS, PS et ES ; le paquet ne contient aucun type de clé de sécurité EdDSA.
ValidAlgorithms vaut null par défaut, et c’est la clé qui décide : un jeton RS256 et un jeton HS256 forgé avec le texte PEM de la clé EC ont tous deux échoué face à une clé EC avec IDX10517: Signature validation failed. Les jetons non signés échouent avec IDX10504, sauf si RequireSignedTokens est défini à false. La lacune porte sur la liaison à la courbe : ES256 a signé avec une clé P-384, et le même gestionnaire a validé le jeton obtenu, ce que d’autres bibliothèques (jose, PyJWT, golang-jwt) refusent. Définissez ValidAlgorithms et utilisez des clés de la bonne taille, comme le fait l’exemple.
Les règles de durée de vie sont l’inverse de celles de la plupart des bibliothèques : exp est obligatoire (IDX10225) et TokenValidationParameters.DefaultClockSkew vaut cinq minutes, si bien qu’un jeton reste accepté jusqu’à cinq minutes après son expiration. C’est généreux pour des jetons d’accès à courte durée de vie : définissez ClockSkew explicitement. CreateToken ajoute exp même quand Expires n’est pas défini.
Les signatures ES256 sont sous la forme r‖s brute de 64 octets qu’exige JWS, ce qui correspond au format par défaut de la classe ECDsa de .NET ; une signature DER échoue avec le même IDX10517 qu’une contrefaçon. Les messages d’erreur masquent le contenu des jetons sous la forme [PII of type ... is hidden], sauf si IdentityModelEventSource.ShowPII est activé pendant le débogage : décodez plutôt le jeton dans le débogueur JWT, et contrôlez les clés d’un fournisseur avec le vérificateur JWKS.