Skip to main content
Avec l’authentification renforcée, les applications qui donnent accès à différents types de ressources peuvent exiger que les utilisateurs s’authentifient au moyen d’un mécanisme plus robuste pour accéder à des informations sensibles ou effectuer certaines transactions. Par exemple, un utilisateur d’une application bancaire peut être autorisé à transférer de l’argent entre des comptes seulement après avoir confirmé son identité au moyen de l’ (MFA). Lorsque votre est une API, vous pouvez implémenter l’authentification renforcée avec Auth0 à l’aide de scopes, de et d’Actions. Lorsqu’une application veut accéder aux ressources protégées d’une API, elle doit fournir un jeton d’accès. Les ressources auxquelles elle aura accès dépendent des autorisations incluses dans le jeton d’accès. Ces autorisations sont définies comme des scopes.

Valider les jetons d’accès pour MFA

En plus de vérifier le scope, l’API doit valider le jeton d’accès pour :
  • Vérifier la signature du jeton, afin de confirmer que l’émetteur du jeton est bien celui qu’il prétend être et de s’assurer que le message n’a pas été modifié en cours de route.
  • Valider les claims standard :

Scénario : Transactions bancaires avec des notifications push

Dans le scénario suivant, une application authentifie un utilisateur avec un nom d’utilisateur et mot de passe, puis demande le solde d’un compte. Avant de récupérer les renseignements sur le solde du compte, l’utilisateur doit s’authentifier au moyen du facteur push Guardian. L’API bancaire peut accepter deux niveaux d’autorisation différents : consulter le solde du compte (scope view:balance) ou transférer des fonds (scope transfer:funds). Lorsque l’application demande à l’API de récupérer le solde de l’utilisateur, le jeton d’accès doit contenir le scope view:balance. Pour transférer de l’argent vers un autre compte, le jeton d’accès doit contenir le scope transfer:funds.

Flux de travail

  1. L’utilisateur se connecte à l’application à l’aide de l’authentification par nom d’utilisateur et mot de passe. La connexion standard lui permet d’interagir avec l’API et de récupérer son solde. Cela signifie que le jeton d’accès que l’application reçoit après l’authentification de l’utilisateur contient le scope view:balance.
  2. L’application envoie une requête à l’API pour récupérer le solde, en utilisant le jeton d’accès comme justificatif d’authentification.
  3. L’API valide le jeton et envoie les renseignements sur le solde à l’application pour que l’utilisateur puisse les consulter.
  4. L’utilisateur veut transférer des fonds d’un compte à un autre, ce qui est considéré comme une transaction de grande valeur nécessitant le scope transfer:funds. L’application envoie une requête à l’API en utilisant le même jeton d’accès.
  5. L’API valide le jeton et refuse l’accès, car il lui manque le scope transfer:funds requis.
  6. L’application redirige l’utilisateur vers Auth0, où une Action sert à lui demander de s’authentifier avec MFA puisqu’un scope de grande valeur a été demandé. Une fois l’authentification MFA réussie, un nouveau jeton d’accès contenant le bon scope est généré et envoyé à l’application dans la réponse.
  7. L’application envoie une autre requête de transfert de fonds en utilisant le nouveau jeton d’accès, qui comprend cette fois le scope transfer:funds.
  8. L’API valide le jeton, l’écarte, puis poursuit l’opération.

Prérequis

Pour ce scénario, vous devez configurer les éléments suivants dans le Dashboard :

Créer une Action

Créez une Action qui demande à l’utilisateur de s’authentifier avec la MFA lorsque le scope transfer:funds est demandé. Accédez à Dashboard > Actions > Flows et créez une Action contenant le contenu suivant :
  • La variable CLIENTS_WITH_MFA contient les des applications auxquelles vous voulez appliquer cette Action. Vous pouvez supprimer cet élément (ainsi que la condition if qui suit) si vous n’en avez pas besoin.
  • La propriété event.transaction.requested_scopes contient tous les scopes demandés par la requête d’authentification. Si elle inclut la valeur transfer:funds, nous demandons alors la MFA en définissant la propriété context.multifactor sur la valeur appropriée. Dans ce cas-ci, nous demandons la MFA au moyen de push.

Configurer l’application

Configurez l’application pour qu’elle envoie à l’API la requête d’authentification appropriée, selon que l’utilisateur tente ou non d’effectuer le transfert de fonds, une transaction de grande valeur. Notez que la seule différence entre les deux requêtes d’authentification (avec ou sans MFA) est le scope.
  • Avec MFA : export const codeExample1 = https://{yourDomain}/authorize? audience=https://my-banking-api& scope=openid%20view:balance%20transfer:funds& response_type=id_token%20token& client_id={yourClientId}& redirect_uri={https://yourApp/callback}& nonce=NONCE& state=OPAQUE_VALUE;
  • Sans MFA : export const codeExample2 = https://{yourDomain}/authorize? audience=https://my-banking-api& scope=openid%20view:balance& response_type=id_token%20token& client_id={yourClientId}& redirect_uri={https://yourApp/callback}& nonce=NONCE& state=OPAQUE_VALUE;

Configurer l’API

Configurez l’API pour valider le jeton entrant et vérifier les permissions autorisées.
  1. Configurez deux points de terminaison pour notre API : GET /balance : pour récupérer le solde actuel POST /transfer : pour transférer des fonds
  2. Utilisez Node.js et plusieurs modules :
    1. express : ajoute le framework d’application web Express.
    2. jwks-rsa : récupère les clés de signature RSA à partir d’un point de terminaison JWKS (JSON Web Key Set). Avec expressJwtSecret, nous pouvons générer un fournisseur de secret qui remettra la bonne clé de signature à express-jwt en fonction du kid dans l’en-tête du JWT.
    3. express-jwt : permet d’authentifier les requêtes HTTP à l’aide de jetons JWT dans vos applications Node.js. Il fournit plusieurs fonctions qui facilitent l’utilisation des JWT.
    4. express-jwt-authz : vérifie si le jeton d’accès contient un scope précis.
  3. Installez les dépendances : npm install express express-jwt jwks-rsa express-jwt-authz --save
  4. Définissez les points de terminaison de l’API, créez une fonction middleware pour valider le jeton d’accès et sécurisez les points de terminaison à l’aide de ce middleware. Le code de votre fichier server.js devrait ressembler à l’exemple de script suivant :
Chaque fois que l’API reçoit une requête, voici ce qui se passe :
  1. Le point de terminaison appelle le middleware checkJwt. 2. express-jwt décode le jeton et transmet la requête, l’en-tête et la charge utile à jwksRsa.expressJwtSecret. 3. jwks-rsa télécharge toutes les clés de signature depuis le point de terminaison JWKS et vérifie si l’une d’elles correspond au kid dans l’en-tête du jeton d’accès. Si aucune clé de signature ne correspond au kid reçu, une erreur est générée. S’il y a correspondance, la bonne clé de signature est transmise à express-jwt. 4. express-jwt poursuit ensuite sa logique pour valider la signature du jeton, l’expiration, l’audience et l’émetteur. 5. jwtAuthz vérifie si le scope exigé par le point de terminaison fait partie du jeton d’accès. Si les scopes précisés sont absents du jeton d’accès, la requête est rejetée avec un message d’erreur 403.

En savoir plus