Passer au contenu principal
Les métadonnées de jeton d’actualisation et les métadonnées de session vous permettent, ensemble, de créer et de stocker des données qui persistent durant tout le cycle de vie de la session Auth0 d’un utilisateur. Cet article présente des exemples pour les cas d’utilisation suivants : Pour en savoir plus, consultez A guide to Auth0 Session and Refresh Token Metadata.
Les métadonnées de session Auth0 ne constituent pas un espace de stockage sécurisé et ne doivent pas servir à stocker des renseignements sensibles. Cela comprend notamment les secrets et les renseignements personnels à haut risque, comme les numéros d’assurance sociale ou de carte de crédit. Il est fortement recommandé aux clients d’Auth0 d’évaluer les données stockées dans les métadonnées et de n’y conserver que celles qui sont nécessaires à des fins de gestion des identités et des accès. Pour en savoir plus, consultez Auth0 General Data Protection Regulation Compliance.

Créer des claims personnalisées persistantes

Les métadonnées du jeton d’actualisation et celles de la session, combinées, vous permettent de créer des claims personnalisées persistantes afin d’étendre les informations contenues dans les jetons ID et d’accès. À l’aide de claims personnalisées persistantes, vous pouvez accéder à des données propres à l’application, comme :
  • Rôles utilisateur
  • Permissions
  • ID de locataire
  • D’autres attributs nécessaires à l’autorisation et à la personnalisation lors des échanges de jetons d’actualisation.
Configurez un déclencheur post-login Action pour créer des claims personnalisées persistantes et les attribuer aux métadonnées du jeton d’actualisation à l’aide de l’objet api.refreshToken.setMetadata().
custom claim Action example
/**
 * @param {Event} event - Détails sur l'utilisateur et la transaction d'authentification.
 * @param {PostLoginActionAPI} api - Interface pour modifier la transaction d'authentification complétée.
 */
exports.onExecutePostLogin = async (event, api) => {
  let customClaimValue1;
  let customClaimValue2;

  // --- Fonction auxiliaire pour simuler le calcul des custom claims ---
  // Dans un scénario réel, cette fonction effectuerait une logique complexe
  // basée sur les données utilisateur, des API externes, etc.
  const calculateCustomClaims = (user) => {
    // Après avoir effectué vos calculs, retourner
    return { claim1: value1, claim2: value2 };
  };

  // --- Déterminer s'il s'agit d'une connexion initiale ou d'un échange de Jeton d'actualisation ---
  // Si event.request.body.grant_type n'est pas 'refresh_token', il s'agit probablement d'une connexion interactive initiale
  const isRefreshTokenGrant = event.request.body.grant_type === 'refresh_token';

  if (!isRefreshTokenGrant) {
    // --- Connexion initiale (p. ex., mot de passe, social, MFA-OOB) ---
    // Calculer les valeurs des custom claims
    const calculatedClaims = calculateCustomClaims(event.user);
    customClaimValue1 = calculatedClaims.claim1;
    customClaimValue2 = calculatedClaims.claim2;

    // Stocker ces valeurs calculées dans les métadonnées du Jeton d'actualisation pour la persistance
    // Vérifier si un Jeton d'actualisation sera émis et, le cas échéant, ajouter les métadonnées
if (event.transaction.requested_scopes.indexOf('offline_access') > -1) {
api.refreshToken.setMetadata('customClaim1', customClaimValue1);
api.refreshToken.setMetadata('customClaim2', customClaimValue2);
}

  } else {
    // --- Échange de Jeton d'actualisation ---
    // Utiliser les valeurs des custom claims provenant des métadonnées du Jeton d'actualisation
    customClaimValue1 = event.refresh_token?.metadata?.customClaim1;
    customClaimValue2 = event.refresh_token?.metadata?.customClaim2;

  } 
  // --- Enfin, ajouter les valeurs déterminées en tant que custom claims aux jetons ---
  api.idToken.setCustomClaim('custom_claim_1', customClaimValue1);
  api.accessToken.setCustomClaim('custom_claim_1', customClaimValue1);

  api.idToken.setCustomClaim('custom_claim_2', customClaimValue2);
  api.accessToken.setCustomClaim('custom_claim_2', customClaimValue2);
};
Lors d’un échange de jeton d’actualisation, un déclencheur Action post-login ultérieur peut accéder à ces claims personnalisées au moyen de l’objet event.refresh_token.metadata et les appliquer aux nouveaux jetons d’actualisation émis à l’aide des objets api.idToken.setCustomClaim() et api.accessToken.setCustomClaim().
Une seule Action post-login peut gérer différents scénarios grant_type à l’aide de l’objet event.request.body.grant_type afin de gérer la persistance des claims. L’objet event.refresh_token est accessible en lecture seule pendant les échanges de jetons d’actualisation.

Créer un identifiant de session unique

Les métadonnées du jeton d’actualisation et celles de la session, combinées, vous permettent de créer un identifiant de session unique afin de mettre en place un identifiant de session persistant qui est conservé pendant toute la durée de la session d’un utilisateur, y compris lors des rotations de jetons d’actualisation. En utilisant des identifiants de session uniques, vous pouvez :
  • Consigner avec précision la session d’un utilisateur à des fins de débogage et d’audit.
  • Fournir aux applications un mécanisme pour suivre l’état interne de la session.
  • Permettre aux API d’offrir une journalisation granulaire, une limitation du taux de requêtes et des décisions d’autorisation contextuelles.
  • Offrir une expérience utilisateur cohérente sur plusieurs cycles de vie de jetons.
Configurez un déclencheur Action post-login pour créer un identifiant de session unique et l’attribuer à la session de l’utilisateur à l’aide des objets api.session.setMetadata() et api.refreshToken.setMetadata(). Ajoutez l’identifiant de session unique comme claim personnalisé aux jetons d’identité et d’accès à l’aide des objets api.idToken.setCustomClaim() et api.accessToken.setCustomClaim().
unique session ID Action example
/**
 * @param {Event} event - Détails sur l'utilisateur et la transaction d'authentification.
 * @param {PostLoginActionAPI} api - Interface pour modifier la transaction d'authentification complétée.
 */
exports.onExecutePostLogin = async (event, api) => {
  let sessionId;

  // 1) Vérifier si une clé de métadonnées de session appelée 'ses_id' existe déjà.
  if (event.session && event.session.metadata && event.session.metadata.ses_id) {
    sessionId = event.session.metadata.ses_id;
  }
  // Si introuvable dans les métadonnées de session, vérifier si elle est disponible dans les métadonnées du jeton d'actualisation.
  // Ceci est particulièrement pertinent pour les flux ROPG où il n'y avait pas de session réelle.
  else if (event.refresh_token && event.refresh_token.metadata && event.refresh_token.metadata.ses_id) {
    sessionId = event.refreshToken.metadata.ses_id;
  }

  // Si 'ses_id' n'existe pas, en générer un nouveau 
  if (!sessionId) {
    sessionId = generateSesId(); // Votre propre fonction utilitaire pour générer un UUID

    // Stocker le 'ses_id' nouvellement généré dans les métadonnées de session
    // N'effectuer cette opération que si une session est réellement émise/présente dans l'événement. 
    if (event.session) {
      api.session.setMetadata('ses_id', sessionId);
    }

    // Stocker le 'ses_id' dans les métadonnées du jeton d'actualisation.
    // N'effectuer cette opération que si un jeton d'actualisation est réellement émis/présent dans l'événement.
    if (event.refresh_token) {
      api.refreshToken.setMetadata('ses_id', sessionId);
    }
  } else {
    // S'assurer également que les métadonnées du jeton d'actualisation contiennent le ses_id, au cas où il serait manquant
    // ou mis à jour ailleurs. Cela peut se produire si l'utilisateur n'a pas demandé offline_access au départ, mais l'a ajouté par la suite.
    if (event.refresh_token && event.refresh_token.metadata && !event.refresh_token.metadata.ses_id) {
        api.refreshToken.setMetadata('ses_id', sessionId);
    }
  }


  // 2) Ajouter ce 'ses_id' comme claim personnalisé à la fois à l'ID Token et au jeton d'accès.
  api.idToken.setCustomClaim('ses_id', sessionId);
  api.accessToken.setCustomClaim('ses_id', sessionId);
};
Lors d’un échange de jeton d’actualisation, un déclencheur Action post-login ultérieur peut accéder à ces claims personnalisés à l’aide de l’objet event.refresh_token.metadata et les appliquer aux nouveaux jetons d’actualisation émis au moyen des objets api.idToken.setCustomClaim() et api.accessToken.setCustomClaim().

Créer un identifiant de locataire

Ensemble, les métadonnées du jeton d’actualisation et les métadonnées de session vous permettent de créer un identifiant de locataire persistant pour gérer des applications multilocataires, où une seule instance d’une application sert plusieurs organisations clientes, et qui est conservé pendant toute la durée de la session d’un utilisateur. En utilisant un identifiant de locataire persistant, vous pouvez :
  • Ajouter un contrôle d’accès dynamique pour appliquer facilement des autorisations propres au locataire dans vos applications et vos API
  • Créer une expérience utilisateur personnalisée afin d’offrir du contenu et des fonctionnalités pertinents selon le contexte de locataire actuel de l’utilisateur
  • Simplifier la logique multilocataire en centralisant l’identification et la propagation du locataire dans Auth0
  • Renforcer la sécurité en évitant l’exposition accidentelle de données entre locataires grâce à un contexte de locataire cohérent dans tous les jetons
  • Améliorer l’évolutivité en réduisant le besoin de requêtes répétées vers la base de données ou d’une logique complexe pour déterminer le contexte de locataire à chaque appel d’API ou actualisation de jeton
Configurez un déclencheur Action post-login pour identifier le locataire actif de l’utilisateur, soit en interrogeant l’application afin d’obtenir une valeur ext-tenantId fournie pendant la demande d’authentification, soit en déduisant le locataire à l’aide de la géolocalisation, soit en invitant l’utilisateur à sélectionner le locataire souhaité. Une fois le locataire identifié, assignez la valeur de l’identifiant de locataire à la session de l’utilisateur à l’aide des objets api.session.setMetadata() et api.refreshToken.setMetadata(), puis ajoutez-la comme claim personnalisé aux jetons d’identification et d’accès à l’aide des objets api.idToken.setCustomClaim() et api.accessToken.setCustomClaim().
tenant identifier Action example
/** 
 * @param {Event} event - Détails sur l'utilisateur et la transaction d'authentification.
 * @param {PostLoginActionAPI} api - Interface pour modifier la transaction d'authentification terminée.
 */
exports.onExecutePostLogin = async (event, api) => {
  let tenantId;

  // 1) Vérifier si une clé de métadonnées de session nommée 'tenant_id' existe déjà.
  if (event.session && event.session.metadata && event.session.metadata.tenant_id) {
    tenantId = event.session.metadata.tenant_id;
  }
  // Si introuvable dans les métadonnées de session, vérifier si elle est disponible dans les métadonnées du jeton d'actualisation.
  // Ceci est particulièrement pertinent pour les flux ROPG où aucune session réelle n'existait.
  else if (event.refresh_token && event.refresh_token.metadata && event.refresh_token.metadata.tenant_id) {
    tenantId = event.refreshToken.metadata.tenant_id;
  }

  // Si le 'tenant_id' est encore inconnu, on le détermine 
  if (!tenantId) {
    // Supposer que tenant_id a été transmis en tant que paramètre ext-
    tenantId = event.request.query['ext-tenantId'];

    // Il pourrait également provenir de la géolocalisation dans l'événement  
    // ou de formulaires. Si vous utilisez des formulaires, ouvrez le formulaire
    // maintenant et exécutez le reste du code dans la 
    // fonction onContinuePostLogin
  
    // Stocker le 'tenant_id' nouvellement déterminé dans les métadonnées de session 
    // Ne faire ceci que si une session est effectivement émise/présente dans l'événement. 
    if (event.session) {
      api.session.setMetadata('tenant_id', tenantId);
    }

    // Stocker le 'tenant_id' dans les métadonnées du jeton d'actualisation.
    // Ne faire ceci que si un jeton d'actualisation est effectivement émis/présent dans l'événement.
    if (event.refresh_token) {
      api.refreshToken.setMetadata('tenant_id', tenantId);
    }
  } else {
    // S'assurer également que les métadonnées du jeton d'actualisation contiennent le tenant_id, au cas où il serait absent
    // ou modifié ailleurs. Cela peut se produire si l'utilisateur n'a pas demandé offline_access au départ, mais l'a ajouté par la suite.
    if (event.refresh_token && event.refresh_token.metadata && !event.refresh_token.metadata.tenant_id) {
        api.refreshToken.setMetadata('tenant_id', tenantId);
    }
  }


  // 2) Ajouter ce 'tenant_id' comme claim personnalisé à la fois au ID Token et au jeton d'accès.
  api.idToken.setCustomClaim('tenant_id', tenantId);
  api.accessToken.setCustomClaim('tenant_id', tenantId);
};
Lors d’un échange de jeton d’actualisation, une Action post-login exécutée par la suite peut accéder à ces claims personnalisés à l’aide de l’objet event.refresh_token.metadata, puis les appliquer aux nouveaux jetons d’actualisation émis au moyen des méthodes api.idToken.setCustomClaim() et api.accessToken.setCustomClaim().

Gérer les données temporaires provenant des fournisseurs d’identité (IdP) en amont

Les métadonnées du jeton d’actualisation et les métadonnées de session vous permettent, ensemble, de gérer les données temporaires et contextuelles provenant des IdP en amont tout au long de la session d’un utilisateur, sans les stocker de façon permanente dans son profil Auth0. Avec les données temporaires, vous pouvez :
  • Garder les profils utilisateur épurés en évitant d’y stocker des données temporaires ou propres à une session
  • Accroître la flexibilité en prenant en charge des besoins en données variés provenant de différents IdP, sans imposer de modifications de schéma ni alourdir les profils utilisateur persistants
  • Améliorer la conformité en facilitant le respect des politiques de confidentialité et de conservation des données, en ne stockant les données temporaires que pendant la durée nécessaire
  • Réduire la charge de développement en simplifiant le traitement des données temporaires des IdP, puisque Auth0 Actions et les métadonnées gèrent le cycle de vie des données
Configurez un déclencheur Action post-login pour identifier les données de profil utilisateur contenues dans les objets event.request, event.user et event.context. Déterminez quelles données sont temporaires ou contextuelles et attribuez-les à la session de l’utilisateur à l’aide des objets api.session.setMetadata() et api.refreshToken.setMetadata(), puis ajoutez les données temporaires comme claim personnalisé aux jetons d’identification et d’accès à l’aide des objets api.idToken.setCustomClaim() et api.accessToken.setCustomClaim().
transient data Action example
/**
 * @param {Event} event - Détails sur l'utilisateur et la transaction d'authentification.
 * @param {PostLoginActionAPI} api - Interface pour modifier la transaction d'authentification complétée.
 */
exports.onExecutePostLogin = async (event, api) => {
  let deviceIdentifier;
  let groups;

  // Exemple : Extraire les informations sur l'appareil à partir des en-têtes de requête ou du contexte
  // À titre indicatif ; l'empreinte réelle de l'appareil pourrait être plus complexe
  if (event.request.user_agent) {
    deviceIdentifier = event.request.user_agent;
  } else {
    deviceIdentifier = 'unknown';
  }

  // Exemple : Extraire les informations de l'IdP à partir du contexte d'une connexion en amont
  // Cela dépend fortement de l'IdP en amont et de la façon dont il transmet les informations.
  // En supposant un claim personnalisé ou une variable de contexte d'une connexion SAML/OIDC, p. ex. "groups"
  if (event.user.groups) {
    groups = event.user.groups;
  } else {
    groups = [];
  }

  // Stocker les données transitoires dans les métadonnées de session
  api.session.setMetadata('deviceIdentifier', deviceIdentifier);
  api.session.setMetadata('groups', groups);

  // Stocker les données transitoires dans les métadonnées du jeton d'actualisation pour la persistance entre les actualisations
  if (event.refreshToken) {
    api.refreshToken.setMetadata('deviceIdentifier', deviceIdentifier);
    api.refreshToken.setMetadata('groups', groups);
  }

  // Facultativement, ajouter ces éléments comme claims aux jetons d'accès si nécessaire pour les API
  // L'utilisation d'espaces de noms personnalisés est une bonne pratique pour les claims spécifiques à l'application.
  api.accessToken.setCustomClaim('https://myapp.example.com/device_id', deviceIdentifier);
  api.accessToken.setCustomClaim('https://myapp.example.com/groups', groups);

  // Exemple : Si l'IdP en amont fournit un « niveau d'assurance » pour cet événement d'authentification
  if (event.transaction && event.transaction.acr_values) { // acr: Authentication Context Class Reference (Référence de classe de contexte d'authentification)
      api.session.setMetadata('authLevel', event.transaction.acr_values);
      if (event.refreshToken) {
        api.refreshToken.setMetadata('authLevel', event.transaction.acr_values);
      }
      api.accessToken.setCustomClaim('https://myapp.example.com/auth_level', event.transaction.acr_values);
  }
};
Lors d’un échange de jeton d’actualisation, un déclencheur Action post-login ultérieur peut accéder à ces claims personnalisés au moyen de l’objet event.refresh_token.metadata et les appliquer aux nouveaux jetons d’actualisation émis à l’aide de la méthode api.accessToken.setCustomClaim().

Renforcer la sécurité et la détection de la fraude

Les métadonnées du jeton d’actualisation et les métadonnées de session vous permettent de mettre en œuvre une sécurité adaptative en suivant et en comparant les informations contextuelles tout au long de la session d’un utilisateur, y compris les rotations de jetons d’actualisation et les demandes d’authentification silencieuse. En mettant en œuvre une sécurité adaptative, vous pouvez :
  • Mettre en place une détection proactive des menaces en repérant et en traitant automatiquement les changements suspects dans les données contextuelles de l’utilisateur, ce qui réduit le risque de détournement de session et d’accès non autorisé.
  • Réduire les frictions pour les utilisateurs légitimes en ne demandant une MFA ou une vérification supplémentaire que lorsqu’une véritable anomalie est détectée, ce qui améliore l’expérience utilisateur par rapport à des exigences de MFA systématiques.
Configurez un déclencheur Action post-login pour identifier les données contextuelles de l’utilisateur, qui peuvent inclure l’empreinte de l’appareil, l’emplacement géographique, les attributs réseau et les attributs comportementaux. Stockez ces données contextuelles dans la session de l’utilisateur à des fins de comparaison, à l’aide de l’objet api.session.setMetadata().
security detection Action example
/**
 * @param {Event} event - Détails sur l'utilisateur et la transaction d'authentification.
 * @param {PostLoginActionAPI} api - Interface pour modifier la transaction d'authentification complétée.
 */
exports.onExecutePostLogin = async (event, api) => {
  // --- Capturer les données contextuelles actuelles ---
  // Utiliser les empreintes ja3/ja4 fournies par Auth0
  const {ja3, ja4} = event.security_context;
  // Ajouter ja3/ja4 aux métadonnées si elles n'y sont pas encore
  // (la première connexion n'a pas de métadonnées définies)
  if (event.session && !event.session.metadata) {
    api.session.setMetadata('ja3', ja3);
    api.session.setMetadata('ja4', ja4);
  } else {
    // Comparer l'empreinte stockée avec l'empreinte entrante 
    if(ja3 != event.session?.metadata?.ja3 || ja4 != event.session?.metadata?.ja4) {
      // Si les empreintes diffèrent, déclencher un défi MFA
      api.authentication.challengeWith(
        { type: 'otp'}, 
        { additionalFactors: [
          { type: 'push-notification'}, { type: 'phone' }
        ]}
      );
    }    
  }
};
Lors d’un échange de jeton d’actualisation ou d’une authentification silencieuse, un déclencheur post-login Action subséquent peut effectuer une évaluation des risques et appliquer des réponses adaptatives.

Accéder aux métadonnées avec la Management API

Vous pouvez utiliser les points de terminaison GET /api/v2/refresh-tokens/{id} et /api/v2/sessions/{id} de la Management API d’Auth0 pour récupérer les données stockées dans les métadonnées d’un jeton d’actualisation ou d’une session. La réponse inclut le champ metadata, qui contient les données stockées :
{
  "id": "object_id",
  "metadata": {
    "deviceIdentifier": "deviceIdentifier"
  }
}

En savoir plus