Any experiences with AD authentication and the Domain\User login syntax?

I am asked to set up a multi-domain AD-login with the LDAPAuthenticator, and the users want to login as domain\username to be able to distinguish between the two domains.

The LDAP Configuration section contains an example for the user@domain notation, which after mixing in the AD specific configuration looks like:


Now I changed the user pattern to:


(so the first part matches the domain and the second one the user name)
and then swapped the other remoteUser configuration settings:


I thought that should work, but it does not; every time a user tries to log in with “domain\login”, the authentication is passed through as domain\\login to the AD.
I think that doubling of the backslash has something to do with LDAP-escaping the Login-expression, but the AD then refuses to accept the login with the double backslash.

Has anyone gotten a similar setup running? Or is the user@domain format the way to go, and domain\user should be avoided?

I don’t see any reason to not use any format you want. But ‘\’ is always a tricky character to find the right number between the various parsers involved…

What do you get in the debug log ?

The log says:

Binding to LDAP server with credentials login=[domain\\user]

followed by a longer exception with root case “Invalid credentials”. It seems the login string passed through to the AD has a double backslash in the login string, even though the users have typed in domain\user.

I see in the code that the LDAP login is constructed here:

ldap/ at master · xwiki-contrib/ldap · GitHub

as MessageFormat.format(getLDAPBindDN(), XWikiLDAPConnection.escapeLDAPDNValue(input), XWikiLDAPConnection.escapeLDAPDNValue(password))

which means that the user input is LDAP-escaped (makes normally sense, definitely), but which causes the input domain\user to be transformed to domain\\user (escaping the \). I guess there is not work around for this, as removing the escaping will allow all kind of interesting user input to be passed through unescaped.

Right, that code assumes that an uid is passed and not a complete DN (so it needs to make sure it’s properly escaped). I guess it would make sense to check in that code if we are in the case in a full DN case (the value is only “{0}”).

A possible workaround would be to use always the same hardcoded user as bind DN instead of building a dynamic one, but that means putting the password in the configuration.