LDAP auth ok but create duplicate users (depends on login format)

GD. I am setup ldap auth, it work fine and i can auth via ldap with both user login format:

short format: username (type from login page)
full format: username@domain.name (type from login page or set via REMOTE_USER header)

but after login, LDAP module create two different XWikiUser profiles:

username (for full format)
username_1 (for short format)

This XWikiUser profiles have same fields from LDAP such dn, first / last name / email / etc. But i think have different uid (uid: username@domain.name and uid: username) …

May be you known why:

  1. Is it possible to LDAP module map full/short username login format in same XWikiUser profile?
  2. If it not possible, may be you known how disable short format login and allow only full login format (always require domain name in uid)?

XWiki 11.10.5
LDAP Authenticator 9.4.4 + LDAP Application 9.4.4
Active Directory as LDAP Server

XWiki uses the case insensitive uid as unique criteria for LDAP users profiles.

The way the login entered in the form is used to find the user in the LDAP server is part of what you configured. Hard to suggest something without knowing how you made two different uid work in the first place.

Finaly after reading source code ldap module around four hours i am found this bug.

My settings:
xwiki.authentication.ldap.remoteUserParser=(.+)@(.+)
xwiki.authentication.ldap.remoteUserMapping.1=uid
xwiki.authentication.ldap.remoteUserMapping.2=domain
xwiki.authentication.ldap.userPageName=${domain}-${uid}
xwiki.authentication.ldap.testLoginFor=${uid}@DOMAIN.NAME

LDAP Module start create new user proccess using this line:

userProfile = syncUser(userProfile, searchAttributes, ldapDn, trimedAuthInput, ldapUtils, context);

Its use trimedAuthInput instead of uid.

Two cases:

If user first login via username only (short format) and then second login via username@domain.name (full format) its create only one new user <<<— because first login trimedAuthInput.equals(uid) -> not run TestLoginFor function. Second login via full format !trimedAuthInput.equeals(uid) -> run TestLoginFor function. Found exist user. No create duplicate. ITS FINE.

If user first login via username@domain.name (full format) and then second login via username only (short format) its create two new user (double) <<<— because first login not found via function TestLoginFor(), and create user with trimedAuthInput as uid in full format. second login via short format not start TestLoginFor because trimedAuthInput.equals(uid) -> user not found -> new dupl user create with short uid. ITS BAD

Why not use: userProfile = syncUser(userProfile, searchAttributes, ldapDn, uid, ldapUtils, context); ?

Or maybe remove check for (!trimedAuthInput.equals(uid)):

    ...
    XWikiDocument userProfile = ldapUtils.getUserProfileByUid(validXWikiUserName, trimedAuthInput, context);
        if (userProfile == null) {
            // Try to search just the UID (in case this user was created before a move to multidomain)
            // if (!trimedAuthInput.equals(uid) && getConfiguration().getTestLoginFor().contains(trimedAuthInput)) {
            if (getConfiguration().getTestLoginFor().contains(trimedAuthInput)) {
                userProfile = ldapUtils.getUserProfileByUid(validXWikiUserName, uid, context);
            }
        } 

Sorry for my Englist. Its not my native.

Yes the LDAP authenticator currently assume that the login is unique for each user. The reason it use the login is because what you are calling the uid in your use case is only unique for a specific domain but when you have several LDAP serveurs you could have two completely different users being toto@domain1.com and toto@domain2.com.

If you want to keep the possibility to support both forms of login I guess we could imagine some configuration to allow customizing the criteria to use to find an existing XWiki profile (in your case the “uid” property). The good thing is that this configuration actually kind of already exist (it’s testLoginFor, by the way I don’t understand why you configured it) but it was designed just as a retro compatibility thing to find profiles generated with a different logic and it’s not currently taken into account to decide what to save in the profile. Would be great if you could create an improvement issue on https://jira.xwiki.org/browse/LDAP.

Supporting only username as login is easy (you pretty much only need to remove all your xwiki.authentication.ldap.remote* setup so that it “breaks” username@domain.name support). But supporting only username@domain.name less so unless you can find a property in your LDAP user which contains username@domain.name in which case you just need to set xwiki.authentication.ldap.UID_attr (and get rid of all your xwiki.authentication.ldap.remote setup because then username@domain.name become the actual UID, you don’t need to parse it anymore) ?