Open aaloise opened 1 month ago
Hi @aaloise it's fine that you've opened an issue here! In order to keep discussion in one place, I've closed your recently opened WordPress support thread and will keep my responses here.
You may want to consider that if a user is created in WordPress with an abc.com email address and that user expects to receive emails at that domain name, they will not receive them if the email is changed from abc.com to xyz.com, or the emails could be sent to someone completely different who has the same xyz.com email address. This is important because password reset emails and other notifications that are sent via WordPress go to the email address on the user's account. Just something to be aware of!
The main hook in Authorizer that you can use to manipulate user data on account creation would be authorizer_user_register
which can be found at https://github.com/uhm-coe/authorizer/blob/master/src/authorizer/class-authorization.php#L291-L310. More on how to create actions when this hook is called can be found at https://developer.wordpress.org/reference/functions/add_action/
So you would want to make your function that will check if the domain name on the email address is abc.com and update it to xyz.com, then create your action with something like:
my_function( $user, $user_data ) {
// ...some code here to check and manipulate email addresses
}
add_action( 'authorizer_user_register', 'my_function', 10, 2 );
I hope that gets you started! Please let us know if you have additional questions.
I was able to get it done! Thanks @pkarjala !
Well, it seems I'm missing something here. I was able to change the users e-mail, but when they try to authenticate again, WP creates a new user with the "old" e-mail, instead of authenticate again with the same user before.
I assume that some work must be done with the hooks, but before that I need to understand the whole process of authentication using LDAP/AD.
Any tips why a new user gets created and what workaround should I use? Thanks again!
Hi @aaloise without seeing your code, it is difficult to determine what might be happening in this case.
It sounds like when the user initially logs in with an abc.com email and is authenticated against LDAP, their email is altered to an xyz.com address using your code and then the user is added to WordPress with the xyz.com email address.
The next time the user attempts to log in, are they using their username or their email address? If they are using their email address, are they logging in with the abc.com or the xyz.com email?
The users authenticate using a username (sAmAccountName) at all moments. The first time, when it doesn't exist in WP, the e-mail is changed to xyz.com and saved in the DB. The second time, instead of authenticate against the recently created user, WP creates a new one using abc.com e-mail in both username and e-mail fields.
The code I am using is this:
function custom_email_domain_change($user, $user_data) {
error_log('Hook authorizer_user_register called');
error_log('User Data: ' . print_r($user_data, true));
if (isset($user_data['email']) && strpos($user_data['email'], '@abc.com') !== false) {
$user_data['email'] = str_replace('@abc.com', '@xyz.com', $user_data['email']);
$user->user_email = $user_data['email'];
wp_update_user(array('ID' => $user->ID, 'user_email' => $user->user_email));
}
error_log('Updated User Email: ' . $user->user_email);
return $user;
}
add_action('authorizer_user_register', 'custom_email_domain_change', 10, 2);
Got it, thank you for sharing your code!
Can you please let us know what is set in the Authorizer configuration under the External Service tab for the field LDAP attribute containing email address
?
Additionally, are the LDAP Directory User
and LDAP Directory User Password
fields set?
The LDAP attribute containing the email address under External Service is "mail".
Yes for both LDAP user and password. They are set.
Just a quick note. The LDAP server is an Active Directory.
Thanks; one more question. Under the Login Access tab, what is set for Who can log into the site?
?
OK, so what we suspect is happening is the following:
The issue is that last one as we do not currently have a way to intercept this process. Instead, however, we suggest trying the following:
LDAP attribute containing email address
, instead of putting mail
, put @xyz.com
instead.Please note that this will only work if your LDAP usernames are an exact match to the first part of the email address before the domain name. So if an LDAP user is pkarjala
, the email address must be pkarjala@abc.com
.
Please give this a try and let us know how it goes!
Steps 1 to 6 are exactly what's happening.
I tried your suggestion, by setting @xyz.com instead of setting "mail" attribute. Unfortunately sAmAccountName is not an exact match to the first part of the e-mail address. The username is an unique ID, so it is a lot of numbers, while e-mail has firstname and lastname.
There is the userPrincipalName attribute, which is firstname.lastname@domain.com. Is there a way we can set it as the username in Authorizer, but remove the @domain.com part, remaining firstname.lastname only during authentication? That way we could set @xyz.com as the LDAP containing e-mail address, which would give us firstname.lastname@xyz.com at the end.
Is that doable?
That might be doable, but another better option may be to create a new field in your AD/LDAP setup that holds something like wordpressEmail
which is a composite of the user's login name and the desired domain name. You would then set this field to be used for the LDAP attribute containing email address
in Authorizer.
This way no custom code is required, but you will need to have that field populated in AD/LDAP on your end.
Sadly I have no management over the domain, other then to retrieve data on it. Because of that I can't create a new attribute.
For now it seems that userPrincipalName is the closest candidate here. But for that I need to use a hook, I supose.
You should be able to use the authorizer_ldap_search_filter
hook to allow users to type in the username portion of userPrincipalName
, and then you append the @domain
portion manually in the hook so the LDAP search finds the user.
https://github.com/uhm-coe/authorizer/blob/master/src/authorizer/class-authentication.php#L1303-L1313
Example:
// If your users log in with just a username, but your LDAP search filter
// matches on an attribute that contains an email address, use this filter to
// append the domain portion of the email address to the username.
// Example search filter (if `userPrincipalName` is the lookup attribute):
// (userPrincipalName=username) => (userPrincipalName=username@domain.com)
add_filter( 'authorizer_ldap_search_filter', function ( $search_filter, $ldap_uid, $username ) {
$search_filter = str_replace( $username, $username . '@domain.com', $search_filter );
return $search_filter;
}, 10, 3 );
It's probably not a good practice to open an issue to ask a question. I was unable to post on the support forum (https://wordpress.org/support/plugin/authorizer/).
The question is actually quite simple, but I haven't found a direction yet. Users in the LDAP domain we have are @abc.com emails and I need this email to be "transformed" to @xyz.com after a successfull authentication.
The closest I found was using functions.php but without success.
If possible, I would like some guidance, and I apologize in advance for using github to ask a simple question.