The problem is that the value for the provider ID is generated incorrectly when the account is loaded.
The provider must always have the prefix ‘openid_copnnect’.

So we need to change this:

$account = $this->externalAuth->load($sub, $this->getPluginId());

to this:

$account = $this->externalAuth->load($sub, 'openid_connect.' . $this->getPluginId());

Issue fork keycloak-3464863

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mhdev90 created an issue. See original summary.

mhdev90’s picture

Issue summary: View changes
guedressel’s picture

I've came to the same conclusion after facing the same issue. @mhde90 Thanks for the fix!

Please note, that the same fix will be introduced with the proposed solution for #3390391: Add keycloak support for multple instances from openid_connect 3.x. That issue handles the underlying story of the changes from openid_connect module.

joseph.olstad’s picture

Status: Needs review » Postponed (maintainer needs more info)

Merge request above no longer applies cleanly to 2.2.x dev.

#3390391: Add keycloak support for multple instances from openid_connect 3.x

The changes in 3390391 are included in 2.2.3-rc1

Postponing this issue upon feedback of 2.2.3-rc1

ivangf15’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new1.72 KB

After further testing I believe the current implementation does not correctly resolve the ExternalAuth provider used by OpenID Connect.

The code currently loads the linked account using:

$this->externalAuth->load($sub, $this->getPluginId());

However `$this->getPluginId()` always resolves to `keycloak`, while the provider stored by ExternalAuth follows the OpenID Connect pattern:

openid_connect.

Example from our setup:

uid | module | authname
----+----------------------+--------------------------------------
5 | openid_connect.portal| c639c7a3-2841-49ed-992c-1aab6efac43f

Because of this mismatch the linked Drupal account cannot be resolved and the email synchronization logic never runs.

The attached patch resolves the provider using the OpenID Connect client id (`parentEntityId`), which matches the provider stored in `authmap`:

openid_connect.

This allows the linked Drupal account to be correctly resolved and the email synchronization to work as expected.

Additionally, the patch introduces a small safety improvement by ensuring the `email` claim exists before attempting synchronization:

!empty($userinfo['email'])

This avoids notices and prevents attempting to update the Drupal account email when the claim is missing from the userinfo response.

MR: https://git.drupalcode.org/project/keycloak/-/merge_requests/50

ivangf15’s picture

After investigating this issue further I confirmed that the problem is caused by the provider used when resolving the ExternalAuth mapping.

The current implementation attempts to load the linked Drupal account using:

$this->externalAuth->load($sub, $this->getPluginId());

However `$this->getPluginId()` always resolves to `keycloak`, while the provider stored by ExternalAuth when using OpenID Connect follows the pattern:

openid_connect.

Example from our setup:

uid | module | authname
----+----------------------+--------------------------------------
5 | openid_connect.portal| c639c7a3-2841-49ed-992c-1aab6efac43f

Because of this mismatch the linked Drupal account cannot be resolved and the email synchronization logic never runs, even when the "Update email address in user profile" option is enabled.

The proposed fix resolves the provider using the OpenID Connect client id (`parentEntityId`), which matches the provider stored in `authmap`:

openid_connect.

This allows the linked Drupal account to be correctly resolved and the email synchronization to work as expected.

Additionally, the change introduces a small safety improvement by ensuring the `email` claim exists before attempting synchronization:

!empty($userinfo['email'])

This prevents notices and avoids attempting to update the Drupal account email when the claim is not present in the userinfo response.

A merge request implementing this fix has been created and is mergeable.