What is the correct way to add custom claims to id_tokens and the /userinfo endpoint and get the complete user profile?

I’m using the new API Authorization features and now my id_token doesn’t include the full user-profile anymore. It only looks like this:

{
  "iss": "https://my_account.auth0.com/",
  "sub": "auth0|42",
  "aud": "...",
  "exp": 1487265822,
  "iat": 1487229822,
  "nonce": "...",
  "at_hash": "..."
}

If I use the issued access_token at the /userinfo endpoint](Authentication API Explorer), I get a response like this:

{"sub":"auth0|42"}

How can I get other properties of the user-profile as well?

The way to figure out if you’re using the new API Authorization features or not is:

  • Check if you pass an audience parameter to the /authorize endpoint
  • Check if the client_id you’re using for the request is marked as OIDC-Conformant under Clients → Settings → Advanced Settings → OAuth
  • Check if you have a Default Audience configured here

You only get a very small subset of the available properties because you are likely not requesting the appropriate scope in the /authorize request. For example, you can try scope=openid profile to see all the possible properties available in id_tokens and on the /userinfo endpoint by default.

If you want to make more properties available to clients through id_tokens or the /userinfo endpoint, you have 2 options:

  1. Trusted clients

Trusted clients may use our Management API v2 to GET a user’s full profile based on only their user_id, which is the sub claim in the id_token and response from /userinfo.

  1. Untrusted clients

For clients that you don’t trust with access to our Management API v2 (such as SPAs, mobile apps, etc.) you will need to setup a Rule like this:

function (user, context, callback) {
  // NOTE: namespace cannot be *.auth0.com
  var namespace = 'http://example.com/';
  context.idToken = context.idToken || {};
  context.accessToken = context.accessToken || {};
  
  context.idToken[namespace + 'myUserId'] = '123';
  context.accessToken[namespace + 'myScope'] = '123';
  
  console.log('+] User', user);
  console.log('+] Context', context);
  callback(null, user, context);
}

With that Rule setup, you should get id_tokens including your custom namespaced claims such as http://example.com/myUserId always, regardless of the scope requested.

Sample id_token with the Rule:

{
  "iss": "https://amaanc-exp.auth0.com/",
  "sub": "auth0|58352a92d4dc5c1f2124ae04",
  "aud": "ynJZ5LNueqMTFAy9SFVjsT8jHM7lv8zc",
  "exp": 1487265949,
  "iat": 1487229949,
  "nonce": "abc",
  "at_hash": "XZEP0MVWmKbYVOzS4l_8qg",
  "http://example.com/myUserId": "123"
}

Please note that the /userinfo endpoint reflects the custom claims that have been added to the id_token via a Rule.

1 Like