Passer au contenu principal
À compter du 28 juillet 2022, Auth0 permettra d’ajouter des revendications personnalisées privées, sans espace de noms, aux jetons d’accès et aux . Ces mêmes revendications seront également ajoutées à la réponse du point de terminaison /userinfo. Pour en savoir plus sur les types de revendications de , consultez Revendications JSON Web Token.
Bien qu’Auth0 autorise l’utilisation de revendications personnalisées privées, sans espace de noms, il recommande fortement d’utiliser des revendications personnalisées publiques avec espace de noms chaque fois que possible. Les revendications personnalisées publiques avec espace de noms constituent le meilleur moyen d’éviter toute collision avec de futures revendications ajoutées à la norme.

Exemple

Auparavant, Auth0 n’autorisait que les revendications assorties d’un espace de noms sur les et les ID tokens. Avec la migration vers les revendications personnalisées, des revendications sans espace de noms peuvent être utilisées sur les jetons d’accès, les ID tokens et le point de terminaison /userinfo de l’Authentication API d’Auth0.
// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // revendications personnalisées publiques avec espace de noms 
  api.accessToken.setCustomClaim('https://myDomain.com/myClaim', 'this is a public, namespaced claim');
  api.idToken.setCustomClaim('https://myDomain.com/myClaim', 'this is a public, namespaced claim');

  // revendications personnalisées sans espace de noms
  api.accessToken.setCustomClaim('myClaim', 'this is a private, non namespaced claim');
  api.idToken.setCustomClaim('myClaim', 'this is a private, non namespaced claim');
};

Flux touchés

Tous les Connect (OIDC) flux pris en charge par Auth0 sont touchés par cette migration. Pour consulter la liste des flux, consultez Flux d’authentification et d’autorisation. Les fonctionnalités suivantes sont également touchées : Les fonctionnalités suivantes ne sont touchées que lorsqu’elles sont utilisées avec Auth0 Rules et le mappage d’attributs :

Restrictions

Taille maximale du jeton

Auth0 limite le payload des revendications personnalisées à un maximum de 100 Ko. Il est important de vous assurer que le payload ne dépasse pas cette limite; sinon, la transaction d’authentification échouera. Nous vous recommandons de vérifier votre utilisation du code d’extensibilité (c.-à-d. Rules, Hooks ou Actions). Portez une attention particulière aux payloads volumineux provenant d’API externes. Pour éviter les erreurs, Auth0 recommande d’utiliser le plus petit payload de jeton nécessaire au fonctionnement de votre application. Vous devrez peut-être supprimer les propriétés non essentielles avant de définir la valeur de la revendication personnalisée.
Cette restriction s’applique à la taille totale du payload de toutes vos revendications personnalisées. Cela inclut les noms des revendications personnalisées ainsi que les valeurs associées, qu’elles soient publiques avec espace de noms ou privées sans espace de noms.
La limite de 100 Ko s’applique séparément aux jetons d’accès et aux ID tokens. Par exemple, un jeton d’accès de 100 Ko et un ID token de 100 Ko peuvent être retournés dans la même transaction.

Exemples

// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // récupération d'un payload supérieur à 100 Ko
  const aHeavyPayload = getHeavyPayload();

  // ceci fera échouer l'authentification
  api.idToken.setCustomClaim('myclaim', aHeavyPayload);

};
// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // récupération d'un payload de 50 Ko
  const a50KBPayload = getHeavyPayload();

  // récupération d'un autre payload de 50 Ko
  const another50KBPayload = getHeavyPayload();

  // ceci fera échouer l'authentification
  api.idToken.setCustomClaim('myclaim', a50KBPayload);
  api.idToken.setCustomClaim('https://myDomain.com/myClaim', another50KBPayload);

};
// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // récupération d'un payload de 50 Ko
  const a50KBPayload = getHeavyPayload();

  // récupération d'un autre payload de 50 Ko
  const another50KBPayload = getHeavyPayload();

  // ceci réussira
  api.accessToken.setCustomClaim('myclaim', a50KBPayload);
  api.idToken.setCustomClaim('https://myDomain.com/myClaim', another50KBPayload);

};

Revendications restreintes

Auth0 limite la personnalisation des revendications utilisées par les normes OIDC ou OAuth2, ainsi que des revendications réservées à un usage interne. Toute tentative de modifier l’une de ces revendications sera ignorée. La transaction n’échouera pas, mais la revendication ne sera pas ajoutée aux jetons. Auth0 recommande d’utiliser une revendication publique dans un espace de noms.
  • acr
  • act
  • active
  • amr
  • at_hash
  • ath
  • attest
  • aud
  • auth_time
  • authorization_details
  • azp
  • c_hash
  • client_id
  • cnf
  • cty
  • dest
  • entitlements
  • events
  • exp
  • groups
  • gty
  • htm
  • htu
  • iat
  • internalService
  • iss
  • jcard
  • jku
  • jti
  • jwe
  • jwk
  • kid
  • may_act
  • mky
  • nbf
  • nonce
  • object_id
  • org_id
  • org_name
  • orig
  • origid
  • permissions
  • roles
  • rph
  • s_hash
  • sid
  • sip_callid
  • sip_cseq_num
  • sip_date
  • sip_from_tag
  • sip_via_branch
  • sub
  • sub_jwk
  • toe
  • txn
  • typ
  • uuid
  • vot
  • vtm
  • x5t#S256

Exemple

// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // ceci sera ignoré
  api.accessToken.setCustomClaim('roles', 'this is a role, but Auth0 will ignore it');

  // ceci réussira et apparaîtra dans le jeton
  api.idToken.setCustomClaim('https://myDomain.com/roles', 'this is a role');

};

Audience de jeton restreinte

Auth0 restreindra la création de revendications personnalisées privées sans espace de noms sur les jetons d’accès dont l’ est une API d’Auth0. Toute tentative de définir une revendication personnalisée privée sans espace de noms sur un jeton d’accès dont l’audience est une API d’Auth0 sera ignorée. La transaction n’échouera pas, mais la revendication ne sera pas ajoutée à votre jeton. Auth0 recommande de ne pas définir de revendications personnalisées sur les jetons destinés à être utilisés par les API d’Auth0.
  • Les ID tokens ne sont pas touchés par cette restriction.
  • Les revendications personnalisées publiques avec espace de noms ne sont pas touchées par cette restriction.
Les audiences suivantes restreignent la création de revendications personnalisées privées sans espace de noms :
  • https://YOUR_TENANT.auth0.com/api ou https://YOUR_TENANT.auth0app.com/api
  • https://YOUR_TENANT.auth0.com/api/v2 ou https://YOUR_TENANT.auth0app.com/api/v2
  • https://YOUR_TENANT.auth0.com/mfa ou https://YOUR_TENANT.auth0app.com/mfa
L’exception à cette restriction est l’audience Auth0 /userinfo. Les revendications personnalisées privées sans espace de noms sont autorisées pour les audiences suivantes :
  • https://YOUR_TENANT.auth0.com/userinfo
  • https://YOUR_TENANT.auth0app.com/userinfo

Exemples

// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // ces revendications seront ignorées si l'audience est une audience Auth0
  api.accessToken.setCustomClaim('myATclaim', 'this is a claim');
  api.accessToken.setCustomClaim('https://myDomain.com/myATclaim', 'this is a claim');

  // celles-ci réussiront, elles ne sont pas touchées par la restriction d'audience
  api.idToken.setCustomClaim('myIdTclaim', 'this is a claim');
  api.idToken.setCustomClaim('https://myDomain.com/myIdTclaim', 'this is a claim');

};
L’exemple ci-dessous illustre la réponse retournée avec des revendications personnalisées si l’audience n’est pas une API Auth0 :
-- Un flux de mot de passe du propriétaire de la ressource 
POST https://{yourTenant}.auth0.com/oauth/token

grant_type:password
username:***
password:***
client_id:***
client_secret:***
audience:https://{yourApi}.com -- Notez l'audience, il s'agit d'une API personnalisée
scope:openid profile
L’exemple ci-dessous montre la réponse renvoyée lorsque des revendications personnalisées ne sont pas ajoutées à l’aide d’une audience d’API Auth0 :
-- Un flux de mot de passe du propriétaire de la ressource 
POST https://{yourTenant}.auth0.com/oauth/token

grant_type:password
username:***
password:***
client_id:***
client_secret:***
audience:https://{yourTenant}.auth0.com/api/v2/ -- Il s'agit d'une audience Auth0 
scope:openid profile
// Le jeton d'accès retourné par Auth0
{
  "iss": "https://{yourTenant}.auth0.com/",
  "sub": ***,
  "aud": [
    "https://{yourTenant}.auth0.com/api/v2/",
    "https://{yourTenant}.auth0.com/userinfo"
  ],
  "iat": 1655283444,
  "exp": 1655369844,
  "azp": ***,
  "scope": "openid profile",
  "gty": "password",

  // La revendication personnalisée avec espace de noms public a été ajoutée, car elle n'est pas visée par cette restriction
  // En revanche, la revendication personnalisée privée sans espace de noms {myATclaim} a été ignorée
  "https://mydomain.com/{myATclaim}": "this is a claim"
}

Restriction concernant les espaces de noms Auth0 et Webtask

Auth0 limitera la création de revendications personnalisées avec espace de noms lorsqu’un domaine Auth0 est utilisé comme identifiant d’espace de noms. Les domaines Auth0 sont :
  • auth0.com
  • webtask.io
  • webtask.run
Toute tentative de définir une revendication personnalisée avec espace de noms dans un jeton en utilisant l’un des domaines ci-dessus comme identifiant sera ignorée. La transaction n’échouera pas, mais la revendication ne sera pas ajoutée à votre jeton.
Avant cette migration, le fait de définir une revendication personnalisée avec espace de noms à l’aide d’un identifiant de domaine Auth0 faisait en sorte que la revendication apparaissait dans la réponse /userinfo. Ce comportement disparaît après la migration et ces revendications personnalisées sont complètement ignorées.
// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // aucune de ces revendications ne sera ajoutée aux jetons ni à la réponse /userinfo
  api.idToken.setCustomClaim('https://example.auth0.com', 'this is a claim');
  api.idToken.setCustomClaim('https://example.webtask.io', 'this is a claim');
  api.idToken.setCustomClaim('https://example.webtask.run', 'this is a claim');

};

Revendications du profil utilisateur OIDC

Auth0 permet désormais d’ajouter des revendications du profil utilisateur OIDC aux jetons d’accès. Avant cette migration, les tentatives d’ajouter des revendications du profil utilisateur OIDC au jeton d’accès étaient ignorées sans avertissement. Avec ce comportement mis à jour, les jetons d’accès contiendront ces revendications du profil utilisateur OIDC.
Si vous ajoutez des revendications du profil utilisateur OIDC aux jetons d’accès, les mêmes restrictions de scope s’appliquent qu’aux ID tokens. Par exemple, pour ajouter la revendication email aux jetons d’accès, le flux doit être déclenché avec un scope qui contient email.
Vous pouvez ajouter les revendications du profil utilisateur OIDC suivantes aux jetons d’accès :
  • address
  • birthdate
  • email
  • email_verified
  • family_name
  • gender
  • given_name
  • locale
  • middle_name
  • name
  • nickname
  • phone_number
  • phone_number_verified
  • picture
  • preferred_username
  • profile
  • updated_at
  • website
  • zoneinfo

Exemple

// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // ceci était ignoré jusqu'à présent. À partir de cette migration, la revendication sera ajoutée aux jetons d'accès 
  // si le scope contient 'email'
  api.accessToken.setCustomClaim('email', 'myemail@domin.com');

  // ceci était ignoré jusqu'à présent. À partir de cette migration, la revendication sera ajoutée aux jetons d'accès 
  // si le scope contient 'profile'
  api.accessToken.setCustomClaim('family_name', 'A family name');

};

Option SAML2 et mise en correspondance des attributs du protocole Web Service Federation (WS-Fed) avec les Rules d’Auth0

Comme lorsque vous utilisez les Rules d’Auth0 pour modifier l’objet utilisateur, les revendications app_metadata ou user_metadata antérieures à la migration fusionnent aussi leur contenu lorsque la revendication est définie sur l’objet context.idToken et qu’il y a conflit de noms. Pour en savoir plus sur les propriétés de l’objet, consultez Propriétés de l’objet utilisateur dans les Rules. Toutefois, lorsque vous utilisez des revendications personnalisées, Auth0 donne priorité à la revendication définie sur l’objet context.idToken object. Ce changement a une incidence sur les Rules d’Auth0 qui définissent app_metadata et user_metadata au moyen de context.id_token (en leur assignant des objets) et qui, en même temps, utilisent ces champs dans la mise en correspondance des attributs pour l’option ou le protocole (WS-Fed). Exemple 1 : Auth0 ignore la mise en correspondance des attributs lorsque context.idToken.app_metadata est défini avec un objet vide.
// une Rule Auth0
function (user, context, callback) {

  user.app_metadata.a_claim = 'This is a claim';
  user.app_metadata.another_claim = 'This is a another claim';

  context.samlConfiguration = context.samlConfiguration || {};

  context.samlConfiguration.mappings = {
    "a_claim": "app_metadata.a_claim",
    "another_claim": "app_metadata.another_claim"
  };

  context.idToken.app_metadata = {};

  return callback(null, user, context);
}
Réponse SAML avant cette migration :
<samlp:Response>
    (...)
    <saml:Assertion>
        (...)
        <saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <saml:Attribute Name="a_claim" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xsi:type="xs:string">
                    This is a claim
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="another_claim" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xsi:type="xs:string">
                    This is a another claim
                </saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>
Réponse SAML avec le nouveau comportement :
<samlp:Response>
    (...)
    <saml:Assertion>
        (...)
        <saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    </saml:Assertion>
</samlp:Response>
Exemple 2 : La version de app_metadata dans context.id_token a préséance.
// un Rule Auth0
function (user, context, callback) {

  user.app_metadata.a_claim = 'This is a claim';
  user.app_metadata.another_claim = 'This is a another claim';

  context.samlConfiguration = context.samlConfiguration || {};

  context.samlConfiguration.mappings = {
    "a_claim": "app_metadata.a_claim",
    "another_claim": "app_metadata.another_claim",
    "claim_set_via_id_token": "app_metadata.claim_set_via_id_token"
  };

  context.idToken.app_metadata = {
  	claim_set_via_id_token: "This is a claim which was set via context.idToken"
  };

  return callback(null, user, context);
}
Réponse SAML avant cette migration :
<samlp:Response>
    (...)
    <saml:Assertion>
        (...)
        <saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <saml:Attribute Name="a_claim">
                <saml:AttributeValue xsi:type="xs:anyType">
                    This is a claim
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="another_claim">
                <saml:AttributeValue xsi:type="xs:anyType">
                    This is a another claim
                </saml:AttributeValue>
            </saml:Attribute>
            <saml:Attribute Name="claim_set_via_id_token">
                <saml:AttributeValue xsi:type="xs:anyType">
                    This is a claim which was set via context.idToken
                </saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>
Réponse SAML avec le comportement mis à jour :
<samlp:Response>
    (...)
    <saml:Assertion>
        (...)
        <saml:AttributeStatement xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <saml:Attribute Name="claim_set_via_id_token" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
                <saml:AttributeValue xsi:type="xs:string">
                    This is a claim which was set via context.idToken
                </saml:AttributeValue>
            </saml:Attribute>
        </saml:AttributeStatement>
    </saml:Assertion>
</samlp:Response>

Ajouter des revendications privées sans espace de noms aux jetons

Le comportement des revendications personnalisées ne changera pas pour les membres du programme bêta des revendications personnalisées. Cette fonctionnalité est déjà activée.
Vous pouvez maintenant ajouter des revendications personnalisées privées sans espace de noms dans le payload des jetons d’accès et des ID tokens.

Exemple

// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // précédemment ignoré
  // À partir de cette migration, la revendication sera ajoutée aux jetons d'accès
  api.accessToken.setCustomClaim('myATclaim', 'this is a claim');

  // précédemment ignoré
  // À partir de cette migration, la revendication sera ajoutée aux ID tokens
  api.idToken.setCustomClaim('myIdTclaim', 'this is a claim');

};

Revendications privées sans espace de noms dans /userinfo

Auth0 renvoie désormais des revendications personnalisées privées sans espace de noms dans la réponse /userinfo lorsqu’elles sont définies dans des ID tokens.

Exemple

// une Auth0 Action 
exports.onExecutePostLogin = async (event, api) => {

  // ceci était ignoré jusqu'à présent. 
  // À partir de cette migration, cette revendication sera retournée dans /userinfo
  api.idToken.setCustomClaim('myIdTclaim', 'this is a claim');

};
-- un appel à /userinfo 
GET https://{yourTenant}.auth0.com/userinfo
Authorization: Bearer {yourAccessToken}
// la réponse de /userinfo
{
    "sub": ***,
    (...)
    "myIdTclaim": "this is a claim"
}

Actions

Consulter les journaux du locataire

Vérifiez d’abord les journaux de votre locataire pour voir si celui-ci est touché par la migration en recherchant des avis de dépréciation.
  1. Accédez à Auth0 Dashboard > Monitoring > Logs.
  2. Recherchez dans les journaux type: depnote AND description: *Custom*claims*.

Exemple

Vous trouverez ci-dessous un exemple de journal de dépréciation généré chaque fois que le code d’extensibilité s’exécute.
{
  "date": "2022-06-28T08:12:52.084Z",
  "type": "depnote",
  "description": "Custom claims must be namespaced: This feature is being deprecated. Please see details.feature of this log for more information.",
  "connection_id": "",
  "client_id": ****,
  "client_name": ****,
  "details": {
    "feature": {
      "grant": "password",
      "access_token_claims_to_be_allowed": [
        "myclaim"
      ],
      "access_token_claims_to_be_disallowed": [
        "gty"
      ],
      "id_token_claims_to_be_allowed": [
        "myclaim"
      ],
      "id_token_claims_to_be_disallowed": [
        "gty"
      ],
      "id": "legacy_custom_claims",
      "name": "Custom claims must be namespaced when they are added through rules / actions / hooks."
    }
  },
  "log_id": ****,
  "_id": ****,
  "isMobile": false,
  "user_agent": "Other 0.0.0 / Other 0.0.0",
  "id": ****
}

Corriger les Rules Auth0 pour l’option SAML2 et le protocole Web Service Federation (Ws-Fed)

Si vous définissez des revendications app_metadata ou user_metadata sur l’objet context.idToken à l’aide de l’option SAML2 ou du protocole Web Service Federation (Ws-Fed) avec les Rules Auth0, ainsi qu’avec le mappage d’attributs, vous devrez mettre à jour votre configuration pour tenir compte de la façon dont Auth0 évalue les noms de revendications en conflit entre ces objets. Plusieurs correctifs sont possibles :
  • Assurez-vous que le code de votre Rule Auth0 donne toujours priorité au contenu des objets définis sur context.id_token :
    // my_claim sera ignorée; cette ligne de code n’est plus pertinente,
    // privilégiez plutôt la définition de my_claim sur `context.idToken`
    user.app_metadata.my_claim = 'a value'; 
    
    // cette version de app_metadata aura priorité sur toute autre modification
    context.idToken.app_metadata = {
      another_claim: 'another value'
    };
    
    // Seule `another_claim` apparaîtra dans les réponses SAML/WsFed
    
  • Si vous utilisez le mappage d’attributs de l’option SAML2 ou du protocole Web Service Federation (Ws-Fed), évitez de définir des revendications app_metadata ou user_metadata sur l’objet context.idToken. Remplacez ces revendications par des revendications avec espace de noms, lorsque possible :
    context.idToken['https://mydomain.com/app_metadata'] = {
      my_claim: 'my claim'
    };
    
  • Utilisez une condition sur le protocole actuel ou sur l’application actuelle pour exclure les instructions qui définissent app_metadata ou user_metadata lorsque le protocole est samlp ou wsfed.
    if (!['samlp', 'wsfed'].includes(context.protocol)) {
        context.idToken.app_metadata = {
          claim_set_via_id_token: "This is a claim which was set via context.idToken"
        };
    }
    

Désactiver l’ancien comportement

Avant de désactiver l’ancien comportement, nous vous recommandons de passer en revue la liste des modifications et de vérifier que vos applications et intégrations sont compatibles.
Si cette option n’apparaît pas dans votre locataire, cela signifie qu’il n’est pas concerné et qu’aucune autre mesure n’est requise.
  1. Accédez à Auth0 Dashboard > Paramètres du locataire > Avancé et recherchez Migrations.
  2. Utilisez le bouton bascule pour désactiver Les revendications personnalisées doivent utiliser un espace de noms.