Problem/Motivation
I have a site with a lot of users and we're adding OpenID Connect. The actual connection is via a custom extension to OpenID Connect Windows Azure AD / B2C which tidies up the email value in $userinfo. The authentication itself is working fine for users that are created from the login process. However, if a user has no entry in the authmap table then we get an error claiming "The e-mail address user@example.com is already taken." and we can't log in.
Proposed resolution
Upon Login via OpenID Connect;
- Connect the Drupal account to the auth provider if configured to allow this and not already connected.
Remaining tasks
Confirm a resolution.Cut code- Review
User interface changes
The Automatically connect existing users setting found in the 8.x branch is added to the OpenID Connect admin config form. This is FALSE by default to maintain historical behaviour for the established install base.
API changes
None.
Data model changes
None
| Comment | File | Size | Author |
|---|---|---|---|
| #38 | Screen Shot 2023-10-18 at 9.00.44 AM.png | 31.38 KB | mcanada |
| #30 | openid_connect-account_claiming-3005824-30.patch | 3.32 KB | odegard |
| #24 | openid_connect-account_claiming-3005824-24.patch | 3.32 KB | james.williams |
Comments
Comment #2
sanduhrsIf you are in control of the OpenID provider, you are also able to spoof the e-mail-address on that account.
So, this is by design.
Comment #3
goldHmm... That makes sense.
Just to confirm though, this does mean that this whole system can only ever be used if the account was created through the use of openid_connect. Is that correct?
Could the system not be set up in such a way that you could link an existing Drupal account that you are already logged into to an openid_connect auth provider?
e.g.,
Comment #4
goldUpdated Problem and Proposed resolution to match what I now know about OC.
Comment #5
goldComment #6
goldIn the absence of a response, and because I consider this to be a major shortcoming of the module, I'm going to make a start on this.
Comment #7
mario steinitzI'll set this feature request back to "Normal" priority. Feel free to provide a patch that suits your needs.
Most probably, this feature can be back-ported from the 8.x version of the module, which has a whole lot of more hooks during the authentication process and even provides the required connect tab within the user account.
Unfortunately, we're kind of busy at the time being and can't provide your feature back-port at once. But we'll happily review contrib patches and see what we can do to add your missing feature in the 7.x version.
Comment #8
goldThanks for the update Mario. I'm just starting this now. I'm happy to provide the patch too.
I'll take a look at the D8 branch too. Although with the differences in the codebase between D7 & D8 I suspect the 'backport' will fall more into that category of movies that were 'inspired by' real events. :)
Comment #9
goldJust an update: I've hit a hurdle with my test environment. Have managed to lock myself out of the UserInfo source. The client has chosen MS Azure AD and Windows Graph is the UserInfo source. So I can login (AD auths okay) but Graph is refusing to accept me.
I'm still working on it. :) Just waiting on the client to fix their end.
Comment #10
goldThis adds the functionality of the Automatically connect existing users option on the 8.x branch to the 7.x branch.
Comment #11
goldUpdating the description to allow for earlier conversation and discovery (the setting in the 8.x branch).
Comment #12
mario steinitzLooks good to me at first sight. I'll do some proper testing over the weekend and set it to RTBC, if it runs without side effects.
Comment #13
mario steinitzIt's working as expected. Setting to RTBC, so we can add it to the next release of the 7.x version.
Comment #14
james.williamsUnfortunately this patch can mistakenly re-enable disabled settings on the admin form. Patch to follow.
Comment #15
james.williamsPatch :-)
See #2834095: openid_connect_always_save_userinfo doesn't update from configuration screen - the intention was that variables always get set, even when defaulted. Additional problem with change made in comment 10's patch here, was that deleting variables when they were unticked was not correct, because they then default to enabled (ticked)!
So this patch just restores what was done in #2834095: openid_connect_always_save_userinfo doesn't update from configuration screen, as there's no real need to treat variables differently if they default differently, nor avoid saving variables.
Comment #16
guypaddock commented#15 LGTM. Reviewed it and tried it out, and it worked pretty well for the use case of allowing an existing user to be associated based on e-mail address for cases in which you trust the IDP.
Did we want to add a note to the UI that informs admins why it might be unsafe to enable the option if the IDP is not 100% trusted?
Comment #17
sano commentedThis is perfect. I use it for a site that has Domain Access module running with two domains. Logging in and out works as well as creation of new accounts. Additionally, if I clone the OpenID Connect plugin*, any of the domains can act as the server or the client.
I think in this context the concern @GuyPaddock mentions does not apply, because there is only one database and it is fully under admin's control.
* as mentioned here https://www.drupal.org/project/openid_connect/issues/2273615
Comment #18
sano commentedIn the context I am mentioning above (Oauth2 server + Domain access module + two OpenID connect clients all running on the same drupal installation) I see a POD exception shown below, after this sequence of steps:
1. open two tabs in a browser
2. load site with domain A into one tab and site with domain B into another
3. clear all cookies for the sites
4. create an account on site with domain A by using the normal drupal registration facility
5. on site with domain B use OpenID connect login button to trigger login using the new account of the domain A site
6. result state: the same user is logged in both sites
7. log off the user on the domain A site
8. use OpenID Connect button on the domain A site to trigger login against the site B
9. the error shown below is thrown
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '56' for key 'authname': INSERT INTO {authmap} (uid, module, authname) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2); Array ( [:db_insert_placeholder_0] => 56 [:db_insert_placeholder_1] => openid_connect_generic [:db_insert_placeholder_2] => 56 ) in user_set_authmaps() (line 2094 of .../modules/user/user.module).Considering that the table schema prevents duplicates in the authname column, one solution could be to set the authname to some combination of the user ID and (say) the domain name, or the module name.
Comment #19
rob holmes commentedUsing the latest patch I am unable to save the new setting, ticking and saving the pages returns the form with the checkbox unticked again.
The actual functionality of the connecting of users works great however (after manual calling a variable_set)
Comment #20
colorfulcoder commentedIf anyone is experiencing the same problem as Rob Holmes, it's because the version 7.x-1.0-beta8 has a bug where the settings are not saved correctly because of the following lines of code: (openid_connect.admin.inc - line 154)
See how variables are only set when the form state values both contains $variable and does not contain $variable? It will never work...
This is not relevant to this issue however, because this issue is about version 7.x-1.x-dev. It already got fixed in 7.x-1.x-dev.
The issue where this was solved is: https://www.drupal.org/project/openid_connect/issues/2834095
Comment #21
dcam commented#15 didn't apply, so I rerolled it.
Comment #22
oldspot commentedI just used patch #21 and can confirm it works great connecting existing user accounts.
Comment #23
jcnventuraI think issue #18 should probably be it's own issue.
Looking at #16, I think that using openid_connect when you don't trust the IDP is already a bad idea. The scenario where all your users use an IDP, but the admin users do not is possible to exploit if you now allow the module to create connections to existing accounts.
I'd prefer that the description of the new option be extended with:
Comment #24
james.williamsSounds reasonable :-) Here's an updated patch then. I've tweaked that messaging slightly as I felt the wording could be improved.
Comment #25
solideogloria commentedThe patch works for me, and it's better than the custom solution I was working with before.
Comment #26
solideogloria commentedComment #27
solideogloria commentedComment #28
elaine.ong commentedHi,
The patch above does not work anymore in version 7.x-1.0.
Appreciate if we can have the patch to enable 'automatically connect existing user' in this version.
Thanks
Comment #29
jcnventuraSorry for the really minor nitpick. But from what I remember, this is flagged as a coding standard violation.
Please, don't use \' to escape the apostrophe when using single quotes. Either skip the contraction (write does not instead of doesn't) or use double quotes around the entire string.
Comment #30
odegard commentedExcellent! I need this module on an existing user base. Here's a patch rerolled for 7.x-1.0.
Adding the patch without checking the new checkbox preserves original behaviour.
Checking the "Automatically connect existing users" creates an authmap entry for the existing account. I also removed the contraction mentioned in issue #29.
Not sure if I can RTBC a patch I rerolled myself, but I will surely start using this in production now.
Thanks!
Comment #31
odegard commentedComment #32
immoreel commentedTested, works as advertised!
Comment #33
moshe weitzman commentedMaybe we should just take this patch since a year has passed and nobody fixed the nitpick.
Comment #34
solideogloria commentedWhat do you mean? The nitpick was fixed in #30 with
doesn\'t->does notComment #35
moshe weitzman commentedOh, I didn't realize that since this is still RTBC. Thanks,
Comment #36
mcanada commentedThis looks like it made to the module, but it is not working for me. I can only login if I manually connect the accounts while logged in as a drupal user. I would like to be able to create a drupal user on the fly if the user is authenticated via oauth.
Any ideas?
Comment #37
solideogloria commented@mcanada, Nothing was ever committed. Did you apply a patch, and which one? Are you using 7.x?
Comment #38
mcanada commented@solideogloria I did not appy any patches. What I mean is that I see the option on the settings (see picture attached) but it doesn't seem to work.

Comment #39
solideogloria commentedThat's not what this option is supposed to do. This option never creates accounts. It claims an existing account that was already created programmatically or by some other login or process. If you want to create an account, you'll have to use a custom module to register an account in the code. At least, that's my understanding.
The option doesn't say "automatically connect non-existing users". It is for connecting OpenID users if there is an existing Drupal account that hasn't been bound to the OpenID user yet.
In my case, we sync information over from Activity Directory in the code and register Drupal accounts for users that didn't have one yet. Then, when they log in via OpenID, we needed to connect them to the new Drupal account.
Comment #40
solideogloria commentedOtherwise, it could be that you need to download a patch or that have have some configuration that needs to be changed.
If you can, use xDebug to step through the code and see what isn't working. Or, share any error messages you see. I'm not on Drupal 7 anymore, but I was using this feature without any problems for years.
Comment #41
mcanada commented@solideogloria Thank you. That makes sense (I think).
I guess what I still don't understand is how the below works
What is the criteria to match a Drupal account to the OpenID user? Name, email?
Comment #42
solideogloria commentedFrom your screenshot, you can see that it's by email address. At least, that's what it is when I use it. That's why is says that without this option, if the email address is already in use, the user won't be able to log in.
Comment #43
mcanada commented@solideogloria yes that is what it says, but it doesn't work. I logged in with my provider and created a d9 user with the same email address. It did not match the accounts.
Comment #44
solideogloria commentedYou'll have to do some more digging then. I use it with Azure AD and it works. Does your provider have the UserPrincipleName (UPN) set to the email address?
Comment #45
solideogloria commentedThe best thing you can do is get xDebug working and use breakpoints to find the source of the issue by stepping through the code.
Comment #47
sanduhrsCommitted, thanks!