Cant bind and search on ActiveDirectory when using AUTH_LDAP_BIND_AS_AUTHENTICATING_USER
This is a nasty corner case when dealing with how some people have set up ActiveDirectory.
This is more of a feature request than a bug, but as it means that there is no way of using django-auth-ldap with login binding I am reporting it as a bug.
Say you are trying to use AUTH_LDAP_BIND_AS_AUTHENTICATING_USER
This means you must set AUTH_LDAP_USER_DN_TEMPLATE
as you can not search until you bind.
But on many ActiveDirectory installs, the primary CN which can be bound against uses the long user name, not the login name. That is it will use something like "CN=Napoleone\5c Doug" instead of the login name 'dnapoleone'.
But the person is entering in their username, not the long name (which users rarely even know!)
This can be worked around by setting AUTH_LDAP_USER_DN_TEMPLATE = "%(user)s@DOMAIN", and binding against that.
But then this is used as the CN for all further operations, so if you are using any of the group features, then the search calls will fail.
The solution is to, after binding, use AUTH_LDAP_USER_SEARCH to search for the full CN which can then be used for future searches.
This is simple enough to fix in backend._LDAPUser:
def _authenticate_user_dn(self, password): """ Binds to the LDAP server with the user's DN and password. Raises AuthenticationFailed on failure. """ if self.dn is None: raise self.AuthenticationFailed("Failed to map the username to a DN.") try: sticky = ldap_settings.AUTH_LDAP_BIND_AS_AUTHENTICATING_USER self._bind_as(self.dn, password, sticky=sticky) ## RED_FLAG: this is the added code, which if both ## AUTH_LDAP_BIND_AS_AUTHENTICATING_USER and ## AUTH_LDAP_USER_SEARCH are set, then re-populate the ## user DN with the result of the search. if sticky and ldap_settings.AUTH_LDAP_USER_SEARCH: self._search_for_user_dn() except self.ldap.INVALID_CREDENTIALS: raise self.AuthenticationFailed("User DN/password rejected by LDAP server.")
Not sure when I will get around to a patch.
It might be better to have an explicit setting to use AUTH_LDAP_USER_SEARCH after binding with AUTH_LDAP_USER_DN_TEMPLATE. Maybe a AUTH_LDAP_USER_DN_SEARCH_AFTER_BIND or something. Due to the corner case I am having a hard time coming up with a good name.