OIDC Enterprise Connection with Okta does not Return Full User Profile

Problem statement

Currently, we are using Auth0’s OpenID Connect Enterprise Connection to integrate our customers’ IdPs with Auth0. During testing, we have found that when integrating with Okta and using OpenID Connect Enterprise Connection’s “back channel” connection type, we are getting “thin” id_tokens from Okta (“thin” id_tokens are id_tokens with most of the claims stripped out). According to OIDC specs, an IdP can return a “thin” id_token when both id_token and access_tokens are requested. The rationale is that the user would then call the userinfo endpoint to get the remaining claims. While “thin” id_tokens are technically part of the OIDC specs, many IdPs do not follow this pattern. Since Auth0’s OpenID Connect Enterprise Connection does not call the userinfo endpoint on our behalf, this leads to inconsistencies in user attributes between IdPs that do send complete id_tokens vs IdPs that send “thin” id_tokens.

We have done many tests to get around the “thin” id_token issue and what we have decided to do is to switch all of our OpenID Connect Enterprise Connections to the “front channel” connection type. This connection type only requests id_tokens, which means we don’t receive “thin” id_tokens anymore.

Symptoms

Not all claims are present in the Auth0 profile when using an OIDC back channel connection with Okta.

Steps to reproduce

  • Create an Okta OIDC application for regular web applications
  • Configure an Auth0 OIDC connection pointed at Okta Client ID
  • Log in as a user and inspect generated user profile

Cause

https://support.okta.com/help/s/article/Okta-Groups-or-Attribute-Missing-from-Id-Token?language=en_US

Okta only returns a “thin” ID token when an access token is also requested, as per an Authorization Code flow. The intention is that the access token will be used to call Okta’s /userinfo endpoint to get the full “fat” ID token with all claims, including custom claims the IdP using Okta may have added.

Solution

Changing the OIDC connection to the front channel will change to using an implicit flow and the full ID token will be returned. This is the simplest fix.

If the back channel is a requirement, a Custom OAuth2 connection can be created to call userinfo automatically after receiving the Okta tokens. This can then be used to map the full profile into Auth0 as required.

https://auth0.com/docs/authenticate/identity-providers/social-identity-providers/oauth2

Sample script:

function fetchUserProfile(accessToken, context, callback) {
  request.get(
    {
      url: 'https://XXXX.okta.com/oauth2/v1/userinfo';,
      headers: {
        'Authorization': 'Bearer ' + accessToken,
      }
    },
    (err, resp, body) => {
      if (err) {
        return callback(err);
      }
      if (resp.statusCode !== 200) {
        return callback(new Error(body));
      }
      let bodyParsed;
      try {
        bodyParsed = JSON.parse(body);
      } catch (jsonError) {
        return callback(new Error(body));
      }
      const profile = {
        user_id: bodyParsed.sub,
        email: bodyParsed.email,
        zoneinfo: bodyParsed.zoneinfo,
        name: bodyParsed.name
      };
      callback(null, profile);
    }
  );
}

There are plans to enhance the OIDC connections to support calling userinfo for example, but the Expected Delivery Timeline is not available yet. We will keep you updated once further information is available.