I’m working on an ASP.NET project for the first time in about three years; in the meantime I’ve been working with Python/Django, PHP and Obj-C. Anyways, picked it right back up… except something that is totally killing me right now, and I have a feeling it must be staring me in the face:
I’m trying to bind to an LDAP server, for the purpose of authenticating users. The way it works here is, you bind on your own credentials, use that to find the Distinguished Name of the user you’re authenticating, then you bind again on their DN and their password. If the bind is successful, the password was correct and the user can be authenticated.
Here’s the problem – the first bind (on the fixed credentials, the ones with the ability to search for users and their subtrees) works fine. The search works fine. The second bind fails, no matter what, with the LDAP error INVALID_CREDENTIALS. This happens even when completely valid credentials are supplied.
Here’s the code, with the usernames and passwords redacted, of course…
public static bool Authenticate(string username, string password)
{
bool valid = false;
try
{
LdapDirectoryIdentifier lid = new LdapDirectoryIdentifier("[[REDACTED]]");
System.Net.NetworkCredential cred = new System.Net.NetworkCredential("[[REDACTED]]", "[[REDACTED]]");
LdapConnection lconn = new LdapConnection(lid);
lconn.Bind(cred);
SearchRequest request = new SearchRequest("[[REDACTED]]", "cn=" + username, SearchScope.Subtree, new String[] { "dn", "sn" });
SearchResponse response = (SearchResponse)lconn.SendRequest(request);
SearchResultEntry rslt = response.Entries[0];
string userdn = rslt.DistinguishedName;
System.Net.NetworkCredential usercred = new System.Net.NetworkCredential(userdn, password);
//we're already in try/catch, so if this fails we'll be booted out
lconn.Bind(usercred);
//otherwise we're all good
valid = true;
}
catch (LdapException e)
{
if (e.ErrorCode == 0x31) //INVALID_CREDENTIALS
throw (e);
//otherwise fall through to DB authentication
}
//DB Auth goes here
return valid;
}
I’ve stepped over this code, reading out the variables and doing the LDAP bind manually (through python-ldap in the python console) and the DN/password combination works fine. What’s going wrong?
From another SO post. If you want to do a rebind using DN, you need to use
AuthType.Basic.You may also like to use
usingwrapping around theLdapConnectionso that you won’t forget to close theLdapConnection.Below is the updated code that should work. Of course, you better have SSL enabled on your LDAP server since the Basic authentication is used.