Account Linking Extension and Accounts on the Same Connection

Overview

When using the account link extension, merging does not behave as expected when a user has multiple accounts on the Identity Provider (IdP).

Applies To

  • Account Link Extension
  • Enterprise Connections

Cause

Some confusion can arise when the user has multiple accounts on a single upstream Identity Provider (IdP), such as an Enterprise OIDC or SAML connection or a custom Social connection with another Auth0 tenant acting as the IdP.

An Auth0 user ID is structured like below when using an enterprise connection:

<STRATEGY>|<ENTERPRISE_CONNECTION_NAME>|<IdP_USER_ID>

Where STRATEGY would be the protocol in use, for example “oidc”, “samlp”, “google-oauth2” etc. (Full list available at Create a connection)

If an Enterprise connection is pointed at another Auth0 tenant, this then compounds the ID naming structure. So, for example, if the “Service Provider” (SP) tenant is using an Enterprise OIDC connection pointed at an upstream IdP Auth0 tenant, which in turn is using a database connection (email+password), then after authentication,n the user will get returned to the SP tenant with an ID that contains the “auth0” strategy:

IdP version of user_id:

user_id: "auth0|xyz123-1234-1234-1234-xyz1234567890"

Which then is stored as the below on the SP tenant:

oidc|enterpriseConnectionName| auth0|xyz123-1234-1234-1234-xyz1234567890

Where italics is the SP tenant’s user ID strategy prefix, and bold is the upstream IdP tenant’s strategy prefix.

If the IdP tenant had other connections enabled, like a Google Social connection, and the user chose to authenticate with this instead when routed by the OIDC connection to the IdP tenant, the SP tenant would get a response like:

IdP version of user_id:

user_id: “google-oauth2|12345678901234567890”

The final user ID in the SP tenant would be:

oidc|enterpriseConnectionName| **google-oauth2|**12345678901234567890

As can be seen, these user_ids will be seen as completely separate identities on the SP tenant as the user IDs are different, despite coming from the same connection (and IdP), as these are distinct identities on the IdP tenant.

If the accounts were also linked on the IdP tenant’s side prior, then only whichever user ID was set as the primary would be returned by the IdP tenant to the SP tenant, regardless of which account they logged into the IdP tenant with, and only one user account would be stored on the SP side.

Solution

The account linking extension is geared for linking users from different IdPs:

“The extension triggers after authentication when the email address of the user who authenticated matches the email address of an existing user account attached to a different identity provider.”

To cater for the scenario laid out above, some additional work is required:

Linking these accounts to the SP tenant would need to be carried out via the Management API.

A.) Either a manual process tenant administrators perform as and when needed using the Management API.
B.) Or using a client or server-side setup like detailed below to allow the user to link their accounts:

These client/server-based scenarios, when attempting to verify that the user owns the other account, could run into the same issue: Their existing “IdP” tenant session is recognized from their cookies and skips the login prompt, returning the same upstream user account that they began the login flow with initially instead of the account that is being verified for linking.

In this scenario, the user would need to be logged out of the IdP tenant before performing the verification or use dynamic upstream parameters to conditionally add “prompt=login” to the connection making the upstream /authorize request. This can force the IdP tenant to prompt the user for their credentials even if they had a session already on the tenant, and thus the user can select the other type of account on the IdP tenant login screen. Please see the below documentation for how to pass dynamic parameters to an upstream IdP:

Alternatively, the “prompt=login” parameter could be added as a static parameter on the connection so that whenever a user has to be passed onto the IdP tenant for authentication, the user will always be able to pick which account to use. However, this would mean that seamless SSO into the upstream IdP tenant would no longer be possible for flows outside of the account linking flows.