> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-fix-docs-5525.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configurer l’authentification renforcée pour les API

> Découvrez comment une API peut vérifier si un utilisateur s’est connecté avec l'authentification multifacteur (MFA) en examinant son jeton d’accès.

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

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
  `;

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
  `;

export const codeExample3 = `   // set dependencies
    const express = require('express');
    const app = express();
    const jwt = require('express-jwt');
    const jwksRsa = require('jwks-rsa');
    const jwtAuthz = require('express-jwt-authz');

    // Create middleware for checking the JWT
    const checkJwt = jwt({
      // Dynamically provide a signing key based on the kid in the header and the signing keys provided by the JWKS endpoint
      secret: jwksRsa.expressJwtSecret({
        cache: true,
        rateLimit: true,
        jwksRequestsPerMinute: 5,
        jwksUri: \`https://{yourDomain}/.well-known/jwks.json\`
      }),

      // Validate the audience and the issuer
      audience: 'https://my-banking-api', // replace with your API's audience, available at Dashboard > APIs
      issuer: 'https://{yourDomain}/',
      algorithms: [ 'RS256' ] // we are using RS256 to sign our tokens
    });

    // create retrieve balance endpoint
    app.get('/balance', checkJwt, jwtAuthz(['view:balance']), function (req, res) {
      // code that retrieves the user's balance and sends it back to the calling app
      res.status(201).send({message: "This is the GET /balance endpoint"});
    });


    // create transfer funds endpoint
    app.post('/transfer', checkJwt, jwtAuthz(['transfer:funds']), function (req, res) {
      // code that transfers funds from one account to another
      res.status(201).send({message: "This is the POST /transfer endpoint"});
    });

    // launch the API Server at localhost:8080
    app.listen(8080);
    console.log('Listening on http://localhost:8080');
`;

Avec l’authentification renforcée, les applications qui permettent d’accéder à différents types de ressources peuvent exiger des utilisateurs qu’ils s’authentifient à l’aide d’un mécanisme plus puissant pour accéder à des informations sensibles ou effectuer certaines transactions.

Par exemple, l’utilisateur d’une application bancaire peut être autorisé à transférer de l’argent entre ses comptes uniquement après avoir confirmé son identité à l’aide de l’authentification multifacteur (<Tooltip href="/docs/fr-ca/glossary?term=multifactor-authentication" tip="Authentification multifacteur (MFA)
Processus d’authentification de l’utilisateur qui utilise un facteur en plus du nom d’utilisateur et du mot de passe, tel qu’un code par SMS." cta="Voir le glossaire">MFA</Tooltip>).

Lorsque votre <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-1" tip="">audience</Tooltip> est une API, vous pouvez mettre en œuvre une authentification renforcée avec Auth0 en utilisant des permissions, des jetons d’accès et des [Actions](/docs/fr-ca/customize/actions). Lorsqu’une application souhaite 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 exprimées sous la forme de [permissions](/docs/fr-ca/get-started/apis/scopes/api-scopes).

## Valider les jetons d’accès pour la MFA

Outre la vérification de la permission, l’API doit [valider le jeton d’accès](/docs/fr-ca/secure/tokens/access-tokens/validate-access-tokens) pour :

* Vérifier la signature du jeton, utilisée pour vérifier que l’expéditeur du jeton est bien celui qu’il prétend être et pour s’assurer que le message n’a pas été modifié en cours de route.
* Valider les demandes standard :

  \| Demande | Description |
  \| --- | --- |
  \| `exp` | Expiration du jeton |
  \| `iss` | Émetteur du jeton |
  \| `aud` | Destinataire du jeton |

## Scénario : Transactions bancaires avec notifications poussées

Dans le scénario suivant, une application authentifie un utilisateur à l’aide de son nom d’utilisateur et de son mot de passe, puis demande le solde de son compte. Avant de récupérer les informations sur le solde du compte, l’utilisateur doit s’authentifier avec le facteur Guardian poussé.

L’API bancaire peut accepter deux niveaux d’autorisation différents : consulter le solde du compte (permission `view:balance`) ou transférer des fonds (permission `transfer:funds`). Lorsque l’application demande à l’API de récupérer le solde de l’utilisateur, le jeton d’accès doit contenir la permission `view:balance`. Pour transférer de l’argent vers un autre compte, le jeton d’accès doit contenir la permission `transfer:funds`.

### Processus

1. L’utilisateur se connecte à l’application en utilisant l’authentification par nom d’utilisateur et mot de passe. La connexion standard permet à l’utilisateur 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 la permission `view:balance`.
2. L’application envoie une demande à l’API pour récupérer le solde, en utilisant le jeton d’accès identifiants.
3. L’API valide le jeton et envoie les informations relatives au solde à l’application, afin que l’utilisateur puisse les consulter.
4. L’utilisateur souhaite transférer des fonds d’un compte à un autre, ce qui est considéré comme une transaction sensible nécessitant la permission `transfer:funds`. L’application envoie une demande à l’API en utilisant le même jeton d’accès.
5. L’API valide le jeton et refuse l’accès parce qu’il manque au jeton la permission `transfer:funds`.
6. L’application redirige vers Auth0, où une action est utilisée pour demander à l’utilisateur de s’authentifier avec la MFA puisqu’un champ d’application de grande valeur a été demandé. Une fois que l’utilisateur s’est authentifié avec succès avec la MFA, un nouveau jeton d’accès comprenant la permission appropriée est généré et envoyé à l’application dans le cadre de la réponse.
7. L’application envoie une autre demande de transfert de fonds à l’aide du nouveau jeton d’accès, qui inclut cette fois la permission `transfer:funds`.
8. L’API valide le jeton, l’ignore et procède à l’opération.

### Prérequis

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

* [Enregistrer une application Web à page unique](/docs/fr-ca/get-started/auth0-overview/create-applications/single-page-web-apps).
* [Créer une connexion de base de données](https://manage.auth0.com/#/connections/database).
* [Enregistrer l’API](/docs/fr-ca/get-started/auth0-overview/set-up-apis). Créez deux permissions : `view:balance` et `transfer:funds`.
* [Activer la MFA](/docs/fr-ca/secure/multi-factor-authentication/enable-mfa) pour utiliser les notifications poussées.

### Créer une action

Créez une action qui demande à l’utilisateur de s’authentifier avec la MFA lorsque la permission `transfer:funds` est demandée. Allez à [Dashboard > Actions > Flux](https://manage.auth0.com/#/actions/flows) et créez une action qui contient ce qui suit :

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const CLIENTS_WITH_MFA = ['REPLACE_WITH_{yourClientId}'];
  // run only for the specified clients
  if (CLIENTS_WITH_MFA.includes(event.client.client_id)) {
    // ask for MFA only if scope transfer:funds was requested
    if (event.transaction.requested_scopes.indexOf('transfer:funds') > -1)
      api.multifactor.enable('any', { allowRememberBrowser: false });
    }
  }
}
```

* La variable `CLIENTS_WITH_MFA` qui contient les identifiants clients des applications à laquelle vous voulez appliquer cette action. Vous pouvez la supprimer (et la condition `if` qui suit) si vous n’en avez pas besoin.
* La propriété `event.transaction.requested_scopes` contient toutes les permissions pour lesquelles la demande d’authentification a été effectuée. 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, nous demandons la MFA en utilisant une notification poussée [push](/docs/fr-ca/secure/multi-factor-authentication/multi-factor-authentication-factors/configure-push-notifications-for-mfa).

### Configurer l’application

Configurez l’application pour qu’elle envoie la demande d’authentification appropriée à l’API, selon que l’utilisateur tente ou non d’effectuer la transaction sensible qu’est le transfert de fonds. Notez que la seule différence entre les deux demandes d’authentification (avec ou sans MFA) est la permission.

* Avec MFA :

<AuthCodeBlock children={codeExample1} language="text" />

* Sans MFA :

<AuthCodeBlock children={codeExample2} language="text" />

| Paramètre       | Réglage                                                                                                                                                                                                                                                                  |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `audience`      | Définissez l’**identifiant** de votre API (trouvez-le dans [API Settings (Paramètres API)](https://manage.auth0.com/#/apis/)). Nous avons réglé le nôtre sur `https://my-banking-api`.                                                                                   |
| `response_type` | Défini sur `id_token token` afin que nous obtenions à la fois un jeton d’ID et un jeton d’accès dans la réponse.                                                                                                                                                         |
| `client_ID`     | Définissez l’ID client de votre application (trouvez-le dans [Application Settings (Paramètres de l’application)](https://manage.auth0.com/#/applications/\{yourClientId}/settings)).                                                                                    |
| `redirect_URI`  | Définissez sur une URL dans votre application vers laquelle Auth0 devrait rediriger l’utilisateur après l’authentification (trouvez-le dans [Application Settings (Paramètres de l’application)](https://manage.auth0.com/#/applications/\{yourClientId}/settings)).     |
| `nonce`         | Défini sur une valeur de chaîne sécurisée qui sera incluse dans la réponse de Auth0. Ceci est [utilisé pour empêcher les attaques par réinsertion de jeton](https://auth0.com/docs/api-auth/tutorials/nonce) et est requis pour le jeton `response_type=id_token token`. |
| `state`         | Défini sur une valeur opaque que Auth0 inclut lors de la redirection vers l’application. Cette valeur doit être utilisée par l’application pour empêcher les attaques CSRF.                                                                                              |

### Configurer l’API

Configurez l’API pour valider le jeton entrant et vérifier les autorisations accordé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](https://expressjs.com/) : ajoute le cadre d’applications Web Express.
   2. [jwks-rsa](https://github.com/auth0/node-jwks-rsa) : récupère les clés de connexion RSA à partir d’un point de terminaison **JWKS** (JSON Web Key Set). À l’aide de `expressJwtSecret` nous pouvons générer un fournisseur de secrets qui fournit la bonne clé de connexion à `express-jwt` en fonction du `kid` dans l’en-tête JWT.
   3. [express-jwt](https://github.com/auth0/express-jwt) : vous permet d’authentifier les requêtes HTTP à l’aide de jetons JWT dans vos applications Node.js. Il fournit plusieurs fonctions qui facilitent le travail avec les JWT.
   4. [express-jwt-authz](https://github.com/auth0/express-jwt-authz) : vérifie si le jeton d’accès contient une permission précise.
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 de médiation pour valider le jeton d’accès et sécurisez les points de terminaison à l’aide de ce logiciel médiateur. Le code de votre fichier `server.js` ressemble à l’exemple de script suivant :

<AuthCodeBlock children={codeExample3} language="javascript" />

Chaque fois que l’API reçoit une demande, il se produit ce qui suit :

1. Le point de terminaison appelle le logiciel médiateur `checkJwt`.
2. `express-jwt` décode le jeton et achemine la demande, l’en-tête et les données utiles vers `jwksRsa.expressJwtSecret`.
3. `jwks-rsa` télécharge toutes les clés de connexion à partir du point de terminaison JWKS et vérifie si l’une des clés de connexion correspond à la valeur `kid` dans l’en-tête du jeton d’accès. Si aucune des clés de connexion ne correspond à la valeur `kid` reçue, une erreur sera générée. S’il y a une correspondance, transmettez la bonne clé de connexion à `express-jwt`.
4. `express-jwt` poursuit sa propre logique pour valider la signature du jeton, l’expiration, l’audience et l’émetteur.
5. `jwtAuthz` vérifie si la permission requise par le point de terminaison fait partie du jeton d’accès. Si les permissions spécifiées sont absents du jeton d’accès, la demande est rejetée avec un message d’erreur 403.

## En savoir plus

* [Jetons d’accès](/docs/fr-ca/secure/tokens/access-tokens)
* [Valider les jetons d’accès](/docs/fr-ca/secure/tokens/access-tokens/validate-access-tokens)
* [Cas d’utilisation des actions](/docs/fr-ca/customize/actions/use-cases)
* [Permissions des API](/docs/fr-ca/get-started/apis/scopes/api-scopes)
* [Configurer l’authentification renforcée pour les applications Web](/docs/fr-ca/secure/multi-factor-authentication/step-up-authentication/configure-step-up-authentication-for-web-apps)
