rt icon indicating copy to clipboard operation
rt copied to clipboard

Allow login with any field from attr_match_list

Open paierh opened this issue 4 years ago • 3 comments

The current implementation of external users does not allow users to use multiple attributes (e.g. uid and email address) to logon to RT. With this simple modification any attribute could be used to identify a user as long as it results in an unique identification.

The UserExists method now searches in the LDAP directory for a match in any of the fields specified with attr_match_list. After an unique match is found (e.g. uid or email address) the provided username is updated to always reflect the value of the "Name" field. Now a user can use any element specified in attr_match_list to logon as long as the provided login data results in an unique result.

I'm not sure if you approve of by-ref-changing of method parameters. An alternative approach would be to rewrite UserExists so it returns the actual username as a string after looking for a match in LDAP or in a database or an empty string if no (unique) match is found.

paierh avatar Oct 05 '19 02:10 paierh

I believe attr_match_list already supports trying multiple attributes for login. It currently attempts the search one at a time. Looking at the commit, it seems the main change is to instead do a single search query with an or (|) instead. Is that correct?

cbrandtbuffalo avatar Oct 07 '19 12:10 cbrandtbuffalo

Actually the main change is to canonicalize $username so that there is only one user in the database for each external user. At the moment we have the following situation: For example let's say that my username is paierh and my email address is [email protected]. On my fisrt login using paierh as username a new user object is created in the RT database with Name=paierh and [email protected] On my second login using [email protected] another NEW user obeject is created with Name=hp@ rt-server.net and Email=NULL instead of loading the existing user from the database.

My patch allows external authentication providers to canonicalize the provided login name before it is looked up in the database.

I solved this by allowing ExternalAuth:: LDAP::UserExists to update the 1st parameter ($username) with the LDAP-Value of attr_name->Name using: $_ [0] = ( $entry -> get_value( $key ))[0];

And then did the same to allow ExternalAuth::UserExists to update $username using: $_ [0] = $username ;

I did not touch DB::UserExists, but the same change would work there also.

I choose the "by ref update" of $_[0] to avoid changes to the function interface, but I think a better way to solve the problem would one of the following:

* Change the return value of UserExists from boolean to string with the canonicalized username as a result 
* Add an additional function call to DoAuth before $session -> { ' CurrentUser ' } -> Load( $username ); to call a new function CanonicalizeUserName 

Regards harald

paierh avatar Oct 07 '19 13:10 paierh

Hi harald

We recently updated related code in 4.4-trunk, to support login using either name or email address, and I believe it could help the scenario of "only one user in the database for each external user".

Could you confirm? Note that you need to specify both "Name" and "EmailAddress" in attr_match_list.

Thanks! -sunnavy

sunnavy avatar Mar 10 '21 16:03 sunnavy