Qu’est-ce qu’un jeton ?
Avant d’introduire les jetons opaques, il est important de comprendre ce qu’est un jeton :
Les jetons sont utilisés pour représenter et transmettre des informations sécurisées entre des parties, et ils soutiennent la grande majorité des processus d’authentification et d’autorisation qui se produisent sur Internet en coulisses. Les deux types de jetons les plus populaires dans les services web sont RFC 7519: JSON Web Tokens (JWT) et les jetons opaques.
Qu’est-ce qu’un jeton opaque ?
Les jetons opaques sont des jetons dans un format propriétaire auquel vous ne pouvez pas accéder et contiennent généralement un identifiant vers des informations dans le stockage persistant d’un serveur.
Un jeton opaque est une forme que peut prendre un jeton, et les jetons d’accès et les jetons de rafraîchissement peuvent exister sous forme de jetons opaques. Le format d’un jeton opaque est déterminé par son issuer (émetteur), et c’est généralement une chaîne de chiffres et/ou de caractères utilisée pour aider l’issuer à récupérer et identifier certaines informations dans une base de données. Voici un exemple de jeton opaque :
M-oxIny1RfaFbmjMX54L8Pl-KQEPeQvF6awzjWFA3iq
D’autre part, un JWT est un autre format de jeton courant. C’est une chaîne JSON qui contient toutes les claims (revendications) et les informations, ainsi qu’une signature de l’issuer. Par défaut, il n’est pas chiffré, bien qu’il puisse être chiffré en utilisant la norme JSON Web Encryption (JWE). Même si le JWT est généralement non chiffré, cela ne compromet pas sa sécurité — la présence de la signature garantit l’intégrité du contenu du jeton, permettant une confiance totale dans les données à l’intérieur du JWT.
Contrairement au JWT, qui contient toutes les informations nécessaires pour être validé directement à la ressource protégée, les jetons opaques ne peuvent pas être validés directement par la ressource. Au lieu de cela, ils nécessitent une validation par l’issuer du jeton opaque (généralement le serveur d’autorisation). Ce processus de validation est généralement appelé introspection de jeton.
Qu’est-ce que JWT ?
À l’opposé des jetons opaques, un JWT est un jeton auto-contenu et sans état qui transporte des informations dans un format structuré et lisible.
Un JWT est composé de trois parties : un header
, un payload
, et une signature
, chacun encodé en Base64URL.
Voici un exemple de JWT :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- Le
header
contient des informations sur le type de jeton et l’algorithme utilisé pour la signature. Par exemple,{"alg": "HS256", "typ": "JWT"}
. - La section
payload
contient des claims — des informations sur l’utilisateur ou l’autorisation — telles que l’ID utilisateur, le temps d’expiration et les scopes. Comme ces données sont encodées mais non chiffrées, quiconque possède le jeton peut le décoder pour voir les claims, bien qu’il ne puisse pas les modifier sans invalider la signature. Selon la spécification et la configuration du serveur d’autorisation, diverses claims peuvent être incluses dans le payload. Cela donne au jeton sa nature auto-contenue. Par exemple,{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
. - La
signature
est générée en combinant le header, le payload, et une clé secrète en utilisant l’algorithme spécifié. Cette signature est utilisée pour vérifier l’intégrité du jeton et s’assurer qu’il n’a pas été altéré.
Les JWT sont couramment utilisés car ils peuvent être vérifiés localement par le client ou par n’importe quel service, sans avoir besoin d’interagir avec le serveur d’autorisation. Cela rend les JWT particulièrement efficaces pour les systèmes distribués, où plusieurs services pourraient avoir besoin de vérifier l’authenticité du jeton de manière indépendante.
Cependant, cette commodité s’accompagne aussi de la responsabilité de veiller à ce que les claims du jeton ne soient pas excessivement exposées, car elles sont visibles pour quiconque a accès au jeton. De plus, les JWT sont généralement de courte durée, et le temps d’expiration est inclus dans les claims du jeton pour garantir que le jeton n’est pas valide indéfiniment.
Validation des jetons d’accès opaques
Un jeton d’accès opaque est validé en l’envoyant de nouveau au serveur d’autorisation pour vérification. Le serveur d’autorisation maintient l’état des jetons émis et peut déterminer la validité du jeton en fonction de son stockage interne.
- Le client demande un jeton d’accès auprès du serveur d’autorisation.
- Le serveur d’autorisation émet un jeton opaque.
- Le client envoie la requête d’accès aux ressources avec le jeton opaque dans l’en-tête.
- Le fournisseur de ressources envoie une requête d’introspection de jeton ( RFC 7662: OAuth 2.0 Token Introspection ) au serveur d’autorisation pour valider le jeton.
- Le serveur d’autorisation répond avec les informations du jeton.
Validation des jetons d’accès JWT (hors ligne)
Un jeton d’accès JWT peut être validé hors ligne par le client ou tout service ayant accès à la clé publique du jeton.
- Le fournisseur de ressources pré-récupère la clé publique du serveur d’autorisation depuis le point de découverte OIDC. La clé publique est utilisée pour vérifier la signature du jeton et assurer son intégrité.
- Le client demande un jeton d’accès auprès du serveur d’autorisation.
- Le serveur d’autorisation émet un jeton JWT.
- Le client envoie la requête d’accès aux ressources avec le jeton JWT dans l’en-tête.
- Le fournisseur de ressources décode et valide le jeton JWT en utilisant la clé publique obtenue du serveur d’autorisation.
- Le fournisseur de ressources accorde l’accès en fonction de la validité du jeton.
Cas d’utilisation dans OIDC
Dans le contexte d’OIDC (OpenID Connect), les jetons opaques et les JWT servent des objectifs différents et sont utilisés dans des scénarios distincts.
Jetons opaques
- Récupération de profil utilisateur :
Par défaut, lorsqu’un client demande un jeton d’accès sans spécifier de ressource et inclut le scope openid
, le serveur d’autorisation émet un jeton d’accès opaque. Ce jeton est principalement utilisé pour récupérer des informations de profil utilisateur depuis le point de terminaison OIDC /oidc/userinfo
. Lorsqu’il reçoit une requête avec le jeton d’accès opaque, le serveur d’autorisation vérifie son stockage interne pour récupérer les informations d’autorisation associées et vérifie la validité du jeton avant de répondre avec les détails du profil utilisateur.
- Échange de jetons de rafraîchissement :
Les jetons de rafraîchissement sont conçus pour être échangés uniquement entre le client et le serveur d’autorisation, sans avoir besoin d’être partagés avec les fournisseurs de ressources. En tant que tels, les jetons de rafraîchissement sont généralement émis sous forme de jetons opaques. Lorsque le jeton d’accès actuel expire, le client peut utiliser le jeton de rafraîchissement opaque pour obtenir un nouveau jeton d’accès, assurant un accès continu sans ré-authentifier l’utilisateur.
JWTs
- Jeton ID :
Dans OIDC, le jeton ID est un JWT qui contient des informations utilisateur et est utilisé pour authentifier l’utilisateur. Généralement émis aux côtés du jeton d’accès, le jeton ID permet au client de vérifier l’identité de l’utilisateur. Par exemple :
// Payload décodé d'un jeton ID
{
"iss": "<https://logto.io>",
"sub": "1234567890",
"aud": "client_id",
"exp": 1630368000,
"name": "John Doe",
"email": "[email protected]",
"picture": "<https://example.com/johndoe.jpg>"
}
Le client peut valider le jeton ID pour assurer l’identité de l’utilisateur et extraire des informations utilisateur pour des besoins de personnalisation ou d’autorisation. Le jeton ID est à usage unique uniquement et ne doit pas être utilisé pour l’autorisation de ressources API.
- Accès aux ressources API (en utilisant le jeton d’accès) :
Lorsqu’un client demande un jeton d’accès avec un indicateur de ressource spécifique, le serveur d’autorisation émet un jeton d’accès JWT destiné à accéder à cette ressource. Le JWT contient des claims que le fournisseur de ressources peut utiliser pour autoriser l’accès du client. Par exemple :
// Payload décodé d'un jeton d'accès JWT
{
"iss": "<https://dev.logto.app>",
"sub": "1234567890",
"aud": "<https://api.example.com>",
"scope": "read write",
"exp": 1630368000
}
Le fournisseur de ressources peut valider la requête en vérifiant les claims :
iss
: Confirme que le jeton a été émis par un serveur d’autorisation de confiance.sub
: Identifie l’utilisateur associé au jeton.aud
: Assure que le jeton est destiné à la ressource spécifique.scope
: Vérifie les permissions accordées à l’utilisateur.