Passer au contenu principal
Vous pouvez utiliser les Actions post-login pour rediriger les utilisateurs avant la fin d’une transaction d’authentification. Cela vous permet de mettre en œuvre des flux d’authentification personnalisés qui nécessitent une interaction utilisateur supplémentaire au-delà du formulaire de connexion standard. Les redirections sont couramment utilisées pour effectuer une authentification multifacteur (MFA) personnalisée dans Auth0, mais elles peuvent aussi servir à :
  • Permettre aux utilisateurs d’accepter une politique de confidentialité personnalisée, des conditions d’utilisation et des formulaires de divulgation de données.
  • Recueillir de façon sécurisée, une seule fois, des données de profil supplémentaires requises.
  • Permettre aux utilisateurs Active Directory distants de modifier leur mot de passe.
  • Exiger des utilisateurs qu’ils fournissent une vérification supplémentaire lorsqu’ils se connectent depuis des emplacements inconnus.
  • Recueillir plus d’informations sur vos utilisateurs que celles qu’ils ont fournies lors de leur inscription initiale.

Vue d’ensemble

Dans les grandes lignes, une Redirect Action fonctionne comme suit :
  1. Une Action effectue une redirection vers une URL.
  2. Le pipeline des Actions est suspendu une fois que cette Action a terminé son exécution.
  3. L’utilisateur est redirigé vers l’URL avec un paramètre state.
  4. Une fois le flux externe terminé, le site externe redirige l’utilisateur vers un point de terminaison /continue avec le paramètre state.
  5. Le pipeline des Actions reprend sur la même Action qui a déclenché la redirection.

Lancer une redirection

Appelez la fonction api.redirect.sendUserTo() comme suit :
/**
* @param {Event} event - Détails sur l'utilisateur et le contexte dans lequel il se connecte.
* @param {PostLoginAPI} api - Interface dont les méthodes permettent de modifier le comportement de la connexion.
*/
exports.onExecutePostLogin = async (event, api) => {
  api.redirect.sendUserTo("https://my-app.exampleco.com");
};
L’exécution de cette Action se termine, puis le pipeline des Actions est suspendu afin de rediriger l’utilisateur vers https://my-app.exampleco.com. Autrement dit, les Actions associées aux déclencheurs post-login qui s’exécutent après l’Action qui invoque la redirection ne s’exécuteront pas tant que le flux d’authentification n’aura pas repris. Si vous connaissez les Redirect Rules, notez qu’il s’agit d’une différence importante entre les Redirect Actions et les Redirect Rules.
Contrairement aux Redirect Rules, les Redirect Actions suspendent le pipeline des Actions lorsqu’une redirection est émise, puis le reprennent dans la même Action lorsque le flux d’authentification se poursuit.
Une fois l’exécution de l’Action terminée, Auth0 redirige l’utilisateur vers l’URL spécifiée dans la fonction api.redirect.sendUserTo(). Auth0 transmet également un paramètre state dans cette URL. Par exemple : https://my-app.exampleco.com/?state=abc123 Votre URL de redirection devra extraire le paramètre state et le renvoyer à Auth0 pour reprendre la transaction d’authentification. Le paramètre state est une valeur opaque utilisée pour prévenir les attaques de falsification de requête intersites (CSRF).

Reprendre le flux d’authentification

Après la redirection, reprenez l’authentification en redirigeant l’utilisateur vers le point de terminaison /continue et en incluant le paramètre state reçu dans l’URL. Si vous ne renvoyez pas le state d’origine au point de terminaison /continue, Auth0 perdra le contexte de la transaction d’authentification et l’utilisateur ne pourra pas se connecter en raison d’une erreur invalid_request. Par exemple : https://{yourAuth0Domain}/continue?state=THE_ORIGINAL_STATE Dans cet exemple, THE_ORIGINAL_STATE est la valeur qu’Auth0 a générée et envoyée à l’URL de redirection. Par exemple, si votre Action redirige vers https://my-app.exampleco.com/, Auth0 utiliserait une URL de redirection semblable à https://my-app.exampleco.com/?state=abc123, ce qui ferait de abc123 la valeur de THE_ORIGINAL_STATE. Pour reprendre la transaction d’authentification, vous redirigeriez vers : https://{yourAuth0Domain}/continue?state=abc123 Lorsqu’un utilisateur est redirigé vers le point de terminaison /continue, le pipeline des Actions reprend à la même Action qui a invoqué la redirection en appelant la fonction onContinuePostLogin. Pour que les redirections fonctionnent correctement, vous devez inclure une fonction ayant la signature suivante dans la même Action qui a invoqué la redirection :
/**
* @param {Event} event - Détails sur l'utilisateur et le contexte dans lequel il se connecte.
* @param {PostLoginAPI} api - Interface dont les méthodes peuvent être utilisées pour modifier le comportement de la connexion.
*/
exports.onExecutePostLogin = async (event, api) => {
  api.redirect.sendUserTo("https://my-app.exampleco.com");
};

/**
* @param {Event} event - Détails sur l'utilisateur et le contexte dans lequel il se connecte.
* @param {PostLoginAPI} api - Interface dont les méthodes peuvent être utilisées pour modifier le comportement de la connexion.
*/

exports.onContinuePostLogin = async (event, api) => {
}

Transmettre des données au site externe

Pour transmettre des données au site externe, nous vous recommandons de les encoder dans un JWT signé afin que votre application puisse s’assurer qu’elles n’ont pas été altérées pendant leur transmission. Avec Actions, vous pouvez le faire à l’aide des fonctions api.redirect.encodeToken et api.redirect.sendUserTo :
/**
* @param {Event} event - Détails sur l'utilisateur et le contexte dans lequel il se connecte.
* @param {PostLoginAPI} api - Interface dont les méthodes peuvent être utilisées pour modifier le comportement de la connexion.
*/
exports.onExecutePostLogin = async (event, api) => {
  const yourDomain = event.secrets.YOUR_AUTH0_DOMAIN || event.request.hostname

  // Créer un jeton de session signé
  const token = api.redirect.encodeToken({
    secret: event.secrets.MY_REDIRECT_SECRET,
    expiresInSeconds: 60, 
    payload: {
      // Claims personnalisés à ajouter au jeton
      email: event.user.email,
      externalUserId: 1234,
      continue_uri: `https://${yourDomain}/continue`
    },
  });

  // Rediriger l'utilisateur vers https://my-app.exampleco.com
  // avec un paramètre de chaîne de requête `session_token` contenant
  // le courriel.
  api.redirect.sendUserTo("https://my-app.exampleco.com", {
    query: { session_token: token }
  });
}
Le code ci-dessus ajoute un paramètre de chaîne de requête session_token à l’URL utilisée pour la redirection (en plus du paramètre state qu’Auth0 ajoute automatiquement). Ce jeton contiendra les éléments suivants :
Token ElementDescription
subLe user_id Auth0 de l’utilisateur.
issLe nom d’hôte du domaine de votre locataire Auth0 (p. ex., example.auth0.com).
expL’heure d’expiration (en secondes) spécifiée avec le paramètre expiresInSeconds. Elle doit être la plus courte possible afin d’éviter la réutilisation du jeton. La valeur par défaut est de 900 secondes (15 minutes).
ipL’adresse IP de la demande d’authentification d’origine.
emailClaim personnalisé dont la valeur est indiquée dans le paramètre payload.email.
externalUserIdClaim personnalisé dont la valeur est indiquée dans le paramètre payload.externalUserId.
signatureÀ l’aide du secret indiqué ci-dessus, le jeton sera signé avec l’algorithme HS256.

Assurez-vous que le jeton n’a pas été altéré

Le système externe doit vérifier que ce jeton n’a pas été altéré pendant sa transmission. Pour ce faire, il doit s’assurer que la signature du jeton est valide et, le cas échéant, que la session du système externe appartient au même utilisateur Auth0 que celui indiqué dans la claim sub du jeton.

Renvoyer des données à Auth0

Une fois que l’utilisateur a terminé le flux personnalisé sur le site externe, il doit être redirigé vers le point de terminaison /continue. Dans certains cas, vous voudrez peut-être renvoyer des données à Auth0 pour influer sur l’authentification ou le de cet utilisateur (par exemple, si vous implémentez des vérifications CAPTCHA ou une personnalisée).

Utilisez les métadonnées d’application lorsque possible

Si possible, le système distant devrait utiliser la Auth0 Management API pour stocker des renseignements personnalisés dans les métadonnées d’application du profil utilisateur Auth0. Lorsque le flux de l’Action Auth0 reprend, ces renseignements sont accessibles dans l’objet event.user.app_metadata. Cette approche évite de transmettre des renseignements sensibles à Auth0 par le canal frontal.

Soyez sélectif lorsque vous stockez des données dans le profil utilisateur Auth0

Évitez de stocker trop de données dans le profil utilisateur Auth0. Ces données sont destinées à des fins d’authentification et d’autorisation. Les fonctions de métadonnées et de recherche d’Auth0 ne sont pas conçues pour des scénarios qui exigent un volume élevé de recherches ou de mises à jour fréquentes, comme les études de marché. Votre système risque de rencontrer des problèmes d’évolutivité et de performance si vous utilisez Auth0 à de telles fins. Si votre application doit accéder à des données utilisateur importantes, l’approche recommandée consiste à stocker ces données dans un système externe et à enregistrer une clé étrangère (l’ID utilisateur) dans Auth0 afin que les systèmes back-end puissent récupérer ces données au besoin.

Envoyer des données sur le canal frontal

Le transfert de données dans les deux sens sur le canal frontal augmente la surface d’attaque exploitable par les . Si vous devez envoyer des données sur le canal frontal, tenez compte des recommandations suivantes :

Transmettre des informations à l’Action

Un jeton de session signé doit être utilisé pour transmettre des informations sensibles à Auth0. Ce jeton peut être validé facilement dans une Action à l’aide du code suivant :
/**
 * @param {Event} event - Détails sur l'utilisateur et le contexte dans lequel il se connecte.
 * @param {PostLoginAPI} api - Interface dont les méthodes peuvent être utilisées pour modifier le comportement de la connexion.
 */
exports.onContinuePostLogin = async (event, api) => {
  const payload = api.redirect.validateToken({
    secret: event.secrets.PRECONFIGURED_SECRET,
    tokenParameterName: 'my_token',
  });

  // utiliser les données encodées dans le token, par exemple : 
  api.idToken.setCustomClaim('color', payload.favorite_color);
}
Le jeton sera validé pour s’assurer que :
  • La signature est valide.
  • Le jeton n’est pas expiré.
  • La claim state du jeton correspond au paramètre state utilisé dans le cadre de la redirection.
Élément du jetonDescription
subuser_id Auth0 de l’utilisateur.
issApplication ciblée par la redirection.
expDoit être aussi court que possible pour éviter la réutilisation du jeton.
stateParamètre state envoyé au site distant dans le cadre de la redirection. Il doit être inclus dans le jeton afin d’éviter les attaques par rejeu.
otherToute autre claim personnalisée sera exposée comme payload dans le code ci-dessus.
signatureLe jeton doit être signé avec l’algorithme HS256.
Pour éviter les attaques par rejeu, le jeton doit être renvoyé à Auth0 au moyen d’une requête POST vers le point de terminaison /continue. L’option tokenParameterName dans le code vous permet de préciser le nom du champ qui contient votre jeton.

Méthodes d’authentification personnalisées

Après une redirection réussie dans le flux de connexion, les Actions peuvent enregistrer des événements de méthode d’authentification personnalisée dans la session de l’utilisateur. Le tableau event.authentication.methods contiendra une entrée pour la méthode personnalisée pendant toute la durée de la session du navigateur de l’utilisateur. Chaque entrée de ce tableau comprend un horodatage indiquant quand la méthode d’authentification a été enregistrée. Une action personnalisée peut déclencher une redirection si la méthode personnalisée requise ne se trouve pas dans le tableau event.authentication.methods ou si l’entrée est trop ancienne. Vous pouvez utiliser api.redirect.sendUserTo() pour envoyer l’utilisateur vers une page qui met en œuvre une méthode d’authentification personnalisée. Vous pouvez utiliser api.authentication.recordMethod() dans le gestionnaire exports.onContinuePostLogin pour enregistrer une entrée de la méthode terminée dans la session de l’utilisateur. L’entrée stockée dans le tableau event.authentication.methods aura une propriété name correspondant à l’URL choisie dans api.authentication.recordMethod(). L’URL enregistrée ici vous permet de rechercher parmi les méthodes d’authentification terminées de la transaction en cours afin de déterminer si votre méthode personnalisée a déjà été exécutée. Votre flux de travail peut exiger que la méthode personnalisée soit exécutée de nouveau périodiquement pendant la durée de la session d’un utilisateur. Par exemple, des scénarios de MFA personnalisés peuvent nécessiter une nouvelle vérification de l’utilisateur après un délai déterminé. L’exemple ci-dessous compare l’horodatage d’une entrée existante afin de déterminer quand réexécuter la méthode personnalisée :
const CUSTOM_METHOD_URL = "https://path.to.prompt";
const PROMPT_TTL = 1000 * 60 * 60 * 24; // 24h

/**
 * Handler that will be called during the execution of a PostLogin flow.
 *
 * @param {Event} event - Details about the user and the context in which
 * they are logging in.
 * @param {PostLoginAPI} api - Interface whose methods can be used to
 * change the behavior of the login.
 */
exports.onExecutePostLogin = async (event, api) => {
  // Search authentication method records for an entry representing our
  // custom method.
  const methodRecord = event.authentication?.methods.find((record) =>
    validateCustomRecord(record, CUSTOM_METHOD_URL, PROMPT_TTL)
  );

  if (!methodRecord) {
    const sessionToken = api.redirect.encodeToken({
      payload: {
        user_id: event.user.user_id,
      },
      secret: event.secrets.SESSION_TOKEN_SECRET,
    });

    // We didn't find a valid record, so we send the user to the
    // URL that implements the custom method with the signed
    // data we encoded in `sessionToken`.
    api.redirect.sendUserTo(CUSTOM_METHOD_URL, {
      query: { session_token: sessionToken },
    });
  }
};

/**
 * Gestionnaire qui sera invoqué lorsque cette action reprend après une
 * redirection externe. Si votre fonction onExecutePostLogin n'effectue pas
 * de redirection, cette fonction peut être ignorée sans risque.
 *
 * @param {Event} event - Détails sur l'utilisateur et le contexte dans lequel
 * il se connecte.
 * @param {PostLoginAPI} api - Interface dont les méthodes peuvent être utilisées pour
 * modifier le comportement de la connexion.
 */
exports.onContinuePostLogin = async (event, api) => {
  const payload = api.redirect.validateToken({
    secret: event.secrets.SESSION_TOKEN_SECRET,
    tokenParameterName: "session_token",
  });

  if (!validateSessionToken(payload)) {
    return api.access.deny("Unauthorized");
  }

  // Record the completion of our custom authentication method.
  // THIS NEW API IS ONLY AVAILABLE IN `onContinuePostLogin`.
  api.authentication.recordMethod(CUSTOM_METHOD_URL);
};

function validateCustomRecord(record, url, ttl) {
  if (!record) {
    // No record means it isn't valid.
    return false;
  }

  if (record.url !== url) {
    // This isn't a record of our custom method.
    return false;
  }

  // Timestamps are rendered as ISO8601 strings.
  const timestamp = new Date(record.timestamp);

  // The record is valid if it was recorded recently enough.
  return timestamp.valueOf() >= Date.now() - ttl;
}

function validateSessionToken(payload) {
  // Custom validation logic for the data returned by the
  // custom method goes here.
  return true;
}
L’API api.authentication.recordMethod() est offerte uniquement dans le gestionnaire exports.onContinuePostLogin. Cela permet d’éviter d’éventuelles exploitations lors de la connexion en enregistrant la méthode personnalisée une fois la redirection terminée.

Restrictions et limites

Les Redirect Actions ne fonctionnent pas avec :

Point de terminaison Resource Owner

Il est impossible d’utiliser des Actions de redirection lorsque vous appelez le point de terminaison Get Token de l’Authentication API pour le flux d’octroi par mot de passe du . Comme l’utilisateur ne se trouve pas dans un flux de redirection au départ, vous ne pouvez pas le rediriger dans une Action.

Flux où prompt=none

Puisque l’objectif de prompt=none est d’éviter toute situation où l’utilisateur devrait fournir une saisie, toute redirection entraînera une erreur error=interaction_required. Comme les Actions s’exécutent après la création d’une session d’authentification, vous ne pouvez pas utiliser prompt=none si vous avez une Rule de redirection qui tente de bloquer l’accès aux jetons dans certaines conditions (par exemple, une MFA personnalisée, un captcha à la connexion, etc.). Vous ne pouvez pas créer un flux de redirection qui bloque l’accès aux jetons et contourne l’Action de redirection avec prompt=none, car après une tentative échouée, un utilisateur peut simplement relancer l’appel avec prompt=none et obtenir des jetons, puisque sa session d’authentification aura déjà été créée, même si les Actions ont échoué la première fois.

Jetons d’actualisation

Comme l’utilisation d’un nécessite un appel sur un canal secondaire au point de terminaison Get Token de l’Authentication API, cette opération échouera également si vous tentez d’effectuer une redirection. Il est difficile de vérifier de façon sécuritaire que les restrictions de connexion ont bien été appliquées. Il n’existe pas d’identifiant de session stable dans le contexte qui pourrait servir à recueillir des renseignements associés à la session, par exemple si cet utilisateur a satisfait aux défis MFA. Par conséquent, vous ne pouvez pas utiliser prompt=none du tout. Chaque fois que api.redirect.sendUserTo() est appelé dans une Action, si prompt=none a été transmis, l’autorisation échoue avec error=interaction_required, mais comme la session de l’utilisateur est créée même si les Actions échouent, nous ne pouvons pas tenir pour acquis qu’un utilisateur a satisfait aux défis de redirection et, par conséquent, nous ne pouvons pas utiliser prompt=none comme moyen d’obtenir des jetons. Dans ce cas précis, nous vous recommandons d’utiliser exclusivement des jetons d’actualisation, car vous pouvez vous assurer qu’un utilisateur a satisfait aux défis si ces défis sont requis pour générer un jeton d’actualisation.

En savoir plus