Meilleures pratiques concernant les jetons

Voici quelques éléments de base à prendre en compte lors de l’utilisation d’un jeton :

  • Gardez-le secret. Gardez-le en sécurité : la clé de connexion doit être traitée comme n’importe quel autre justificatif d’identité et n’être révélée qu’aux services qui en ont besoin.

  • N’ajoutez pas de données sensibles à la charge utile : les jetons sont signés afin de les protéger contre toute manipulation et sont facilement décodés. Pour obtenir une performance et une sécurité optimales, ajoutez le nombre minimal de demandes à la charge utile.

  • Donnez une date d’expiration aux jetons : techniquement, une fois qu’un jeton est signé, il est valable pour toujours, à moins que la clé de connexion ne soit modifiée ou que l’expiration ne soit explicitement définie. Cela peut poser des problèmes potentiels, raison pour laquelle il convient de prévoir une stratégie d’expiration et/ou de révocation des jetons.

  • Adoptez le protocole HTTPS : n’envoyez pas de jetons via des connexions non HTTPS, car ces demandes peuvent être interceptées et les jetons compromis.

  • Considérez tous vos cas d’utilisation d’autorisation : l’ajout d’un système secondaire de vérification des jetons qui garantit que les jetons ont été générés à partir de votre serveur peut s’avérer nécessaire pour répondre à vos besoins.

  • Stockez et réutilisez : limitez les allers-retours inutiles qui étendent la surface d’attaque de votre application et optimisez les limites de jetons du plan (le cas échéant) en stockant les jetons d’accès obtenus auprès du serveur d’autorisation. Au lieu de demander un nouveau jeton, utilisez le jeton stocké lors d’appels ultérieurs jusqu’à son expiration. Le mode de stockage des jetons dépend des caractéristiques de votre application : les solutions habituelles comprennent les bases de données (pour les applications qui doivent effectuer des appels API indépendamment de la présence d’une session) et les sessions HTTP (pour les applications dont la fenêtre d’activité est limitée à une session interactive). Pour un exemple de stockage côté serveur et de réutilisation des jetons, consultez Stockage des jetons.

Jetons par rapport aux Témoins

En général, les applications à une page (telles que React, Vue et AngularJS + Node), les applications mobiles natives (telles que iOS et Android) et les API Web (écrites en Node, Ruby, ASP.NET ou une combinaison de ces technologies) bénéficient le plus de l’authentification basée sur des jetons. Les applications Web traditionnelles côté serveur ont généralement eu recours à l’authentification basée sur les témoins.

L’authentification par jeton est mise en œuvre en générant un jeton lorsque l’utilisateur s’authentifie, puis en définissant ce jeton dans l’en-tête Autorisation de chaque demande ultérieure adressée à votre API. Ce jeton doit être standard, comme les jetons Web JSON, car la plupart des plates-formes disposent de bibliothèques à cet effet et qu’il n’est pas nécessaire de créer son propre système de cryptographie.

Ces deux approches vous permettent d’obtenir la même quantité d’informations de la part de l’utilisateur. Cela est contrôlé par le paramètre scope envoyé dans la demande de connexion (soit en utilisant Lock, notre bibliothèque JavaScript ou un simple lien). Scope est un paramètre de la méthode .signin({scope: ’openid name email’}) qui finit par faire partie de la chaîne de requête dans la demande de connexion.

Par défaut, nous utilisons scope=openid dans l’authentification par jeton pour éviter d’avoir un jeton trop volumineux. Vous pouvez contrôler toutes les demandes OpenID Connect (OIDC) standard que vous souhaitez obtenir dans le jeton en les ajoutant en tant que valeurs scope (permission). Par exemple, scope=openid name email family_name address phone_number. Pour en savoir plus, consultez Demandes standard sur openid.net.

Vous pouvez combiner l’authentification par jeton avec l’authentification par témoin. Tenez compte du fait que les témoins fonctionneront parfaitement si l’application web et l’API sont servies par le même domaine, de manière à vous dispenser d’une authentification par jeton. Au besoin, nous renvoyons également un JWT dans le flux de l’application web. Chacune de nos trousses SDK procède à cette opération de manière différente. Si vous souhaitez appeler vos API à partir de JavaScript (au lieu d’utiliser le témoin existant), vous devez définir les jetons d’accès à l’aide de Web Workers ou de fermetures JavaScript pour gérer les transmissions et le stockage des jetons. Pour en savoir plus, lisez la section Scénarios de navigation en mémoire de notre page Stockage de jetons.

Utilisation du jeton d’actualisation

Le jeton d’actualisation ne peut être obtenu que si vous mettez en œuvre les flux suivants :

Si vous limitez l’accès hors ligne à votre API, une mesure de protection configurée via l’option Autoriser l’accès hors ligne dans Auth0 Dashboard > Applications > API > Settings (Paramètres), Auth0 ne renverra pas de jeton d’actualisation pour l’API (même si vous incluez la permission offline_access dans votre demande).

Les règles s’appliqueront à l’échange de jetons d’actualisation. Pour exécuter une logique spéciale, vous pouvez examiner la propriété context.protocol dans votre règle. Si la valeur est oauth2-refresh-token, la règle s’exécute pendant l’échange.

Lorsque vous essayez d’obtenir un jeton d’actualisation, le paramètre audience n’est pas disponible dans l’objet de contexte Règles. Si un message d’erreur s’affiche lorsque vous tentez d’ajouter le paramètre audience, vérifiez que ce paramètre n’est pas défini pour le jeton.

Si vous essayez de faire une redirection avec context.redirect, le flux d’authentification renverra une erreur.

Si vous avez ajouté des demandes personnalisées à vos jetons en appliquant une règle, les demandes personnalisées apparaîtront dans les nouveaux jetons émis lors de l’utilisation d’un jeton d’actualisation tant que votre règle sera appliquée. Bien que les nouveaux jetons n’héritent pas automatiquement des demandes personnalisées, les règles s’exécutent pendant le flux du jeton d’actualisation, ce qui signifie que le même code sera exécuté. Cela vous permet d’ajouter ou de modifier des demandes personnalisées dans les jetons nouvellement émis sans contraindre les applications précédemment autorisées à obtenir un nouveau jeton d’actualisation.

Limites des jetons d’actualisation

Auth0 limite le nombre de jetons d’actualisation actifs à 200 par utilisateur et par application. Cette limite ne s’applique qu’aux jetons actifs. Si la limite est atteinte et qu’un nouveau jeton d’actualisation est créé, le système révoque et supprime le jeton le plus ancien pour cet utilisateur et cette application. Les jetons retirés et expirés ne comptent pas dans la limite.

Tests automatisés

Les jetons d’actualisation s’accumulent en raison des tests automatisés et sont généralement utilisés pendant toute la durée du test. Pour éviter une accumulation de jetons soumise à des limites de jetons d’actualisation, utilisez l’Auth0 Management API pour supprimer les jetons d’actualisation inutiles.

  1. Créez un utilisateur avec Management API. L’utilisateur créé vous servira à effectuer des tests.

  2. La réponse renvoie un user_id que vous devez conserver pendant les tests afin de l’utiliser ultérieurement.

  3. Une fois les tests terminés, supprimez l’utilisateur via Management API. Lorsque l’utilisateur de test est supprimé, les artefacts associés sont également supprimés, y compris les jetons d’actualisation.

Si vous souhaitez conserver l’utilisateur de test pour des tests ultérieurs :

  1. Dressez la liste des jetons d’actualisation de l’utilisateur à l’aide du point de terminaison des identifiants d’appareil de Management API . Le point de terminaison renverra un maximum de 1000 jetons sans ordre spécifique, indépendamment des jetons accumulés ou de l’utilisation de la pagination.

  2. Supprimez ces identifiants en utilisant la méthode DELETE.

  3. Si l’utilisateur dispose de plus de 1 000 jetons, refaites la liste et supprimez des jetons jusqu'à ce qu'il n'en reste plus pour l'utilisateur.

Configuration des jetons d’actualisation sur le point d’expirer

Lorsque les utilisateurs se connectent à votre application avec Auth0 et que offline_access est demandé dans la requête d’autorisation, un nouveau jeton d’actualisation est émis pour l’utilisateur. Si l’utilisateur se déconnecte et se reconnecte avec le même appareil, un nouveau jeton d’actualisation est émis. Selon la manière dont votre application stocke et utilise les jetons d’actualisation, l’ancien jeton d’actualisation utilisé lors de la première connexion peut devenir obsolète. Votre application utilisera très probablement les nouveaux jetons d’actualisation si les deux jetons sont émis avec la même audience. Pour en savoir plus, lisez Stockage des jetons.

Pour éviter d’accumuler des jetons d’actualisation obsolètes, même si la limite de jetons d’actualisation supprime d’abord le jeton le plus ancien, nous vous recommandons de configurer le délai d’expiration des jetons d’actualisation. Vous pouvez configurer les jetons d’actualisation avec ou sans rotation (ou réutilisables) de manière à ce qu’ils expirent avec des valeurs d’expiration inactives ou absolues. Ces deux valeurs d’expiration permettent de supprimer les jetons non utilisés activement et d’éviter l’accumulation de jetons pour l’utilisateur. Pour en savoir plus, consultez Configurer le délai d’expiration du jeton d’actualisation.

Validation JWT

Nous vous recommandons vivement d'utiliser un logiciel médiateur ou l'une des bibliothèques tierces au code source libre existantes pour analyser et valider les JWT. Dans JWT.io, vous trouverez des bibliothèques pour différentes plateformes et différents langages, comme .NET, Python, Java, Ruby, Objective-C, Swift et PHP.

Algorithmes de signature

L’algorithme utilisé pour signer les jetons émis pour votre application ou votre API. Une signature est incluse dans un JWT et sert à vérifier que l’expéditeur du jeton est bien celui qu’il prétend être et à s’assurer que le message n’a pas été modifié en cours de route. Pour en savoir plus sur les JWT, lisez Jetons Web JSON. Pour en savoir plus sur les signatures, lisez Structure de jetons Web JSON.

Vous pouvez choisir parmi les algorithmes de signature suivants :

  • RS256 (Signature RSA avec SHA-256): Algorithme asymétrique, ce qui signifie qu’il y a deux clés : une clé publique et une clé privée qui doit être gardée secrète. Auth0 possède la clé privée utilisée pour générer la signature, et le consommateur du JWT récupère une clé publique à partir des points de terminaison des métadonnées fournis par Auth0 et l’utilise pour valider la signature du JWT.

  • HS256 (HMAC avec SHA-256): Un algorithme symétrique, ce qui signifie qu’il n’y a qu’une seule clé privée qui doit être gardée secrète et qui est partagée entre les deux parties. Étant donné que la même clé est utilisée à la fois pour générer la signature et pour la valider, il convient de veiller à ce que la clé ne soit pas compromise. Cette clé privée (ou secret) est créée lorsque vous enregistrez votre application (Secret Client) ou votre API (Secret de signature) et que vous choisissez l’algorithme de signature HS256.

La pratique la plus sûre, et notre recommandation, est d’utiliser RS256 pour les raisons suivantes :

  • Avec RS256, vous êtes sûr que seul le détenteur de la clé privée (Auth0) peut signer les jetons, tandis que n’importe qui peut vérifier si le jeton est valide à l’aide de la clé publique.

  • Avec RS256, vous pouvez demander un jeton valide pour différents publics.

  • Avec RS256, si la clé privée est compromise, vous pouvez mettre en œuvre la rotation des clés sans avoir à redéployer votre application ou votre API avec le nouveau secret (ce que vous devriez faire si vous utilisiez HS256).

  • Avec HS256, si la clé secrète est compromise, vous devez redéployer l’API avec le nouveau secret.

Clés de connexion

Une bonne pratique consiste à supposer que plusieurs clés de connexion peuvent être présentes dans votre JWKS. Cela peut sembler inutile puisque le point de terminaison Auth0 JWKS contient généralement une seule clé de connexion; cependant, plusieurs clés peuvent se trouver dans le JWKS lors de la rotation des certificats de signature.

Nous vous recommandons de mettre en cache vos clés de connexion afin d’améliorer les performances de l’application et d’éviter de vous heurter à des limites anti-attaques. Toutefois, si le décodage d’un jeton échoue, vous devez vous assurer d’invalider le cache et de récupérer de nouvelles clés de connexion avant de réessayer une dernière fois.

En savoir plus