Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I validate Active Directory creds over LDAP + SSL?

I'm trying to use the .NET 3.5 System.DirectoryServices.AccountManagement namespace to validate user credentials against our Active Directory LDAP server over an SSL encrypted LDAP connection. Here's the sample code:

using (var pc = new PrincipalContext(ContextType.Domain, "sd.example.com:389", "DC=sd,DC=example,DC=com", ContextOptions.Negotiate))
{
    return pc.ValidateCredentials(_username, _password);
}

This code works fine over unsecured LDAP (port 389), however I'd rather not transmit a user/pass combination in clear text. But when I change to LDAP + SSL (port 636), I get the following exception:

System.DirectoryServices.Protocols.DirectoryOperationException: The server cannot handle directory requests.
  at System.DirectoryServices.Protocols.ErrorChecking.CheckAndSetLdapError(Int32 error)
  at System.DirectoryServices.Protocols.LdapSessionOptions.FastConcurrentBind()
  at System.DirectoryServices.AccountManagement.CredentialValidator.BindLdap(NetworkCredential creds, ContextOptions contextOptions)
  at System.DirectoryServices.AccountManagement.CredentialValidator.Validate(String userName, String password)
  at System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials(String userName, String password)
  at (my code)

Port 636 works for other activities, such as looking up non-password information for that LDAP/AD entry...

UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, _username)

...so I know it's not my LDAP server's SSL setup, since it works over SSL for other lookups.

Has anyone gotten the ValidateCredentials(...) call to work over SSL? Can you explain how? Or is there another/better way to securely validate AD/LDAP credentials?

like image 761
Nate Sauber Avatar asked Jun 01 '12 13:06

Nate Sauber


People also ask

How does LDAP authentication work with AD?

How does LDAP work with Active Directory? LDAP provides a means to manage user and group membership stored in Active Directory. LDAP is a protocol to authenticate and authorize granular access to IT resources, while Active Directory is a database of user and group information.

How do I enable SSL in Active Directory?

Select Start | All Programs | Windows Support Tools | Command Prompt. Start the ldp tool by typing ldp at the command prompt. From the ldp window, select Connection | Connect and supply the host name and port number (636). Also select the SSL check box.


1 Answers

I was able to validate credentials using the System.DirectoryServices.Protocols namespace, thanks to a co-worker. Here's the code:

// See http://support.microsoft.com/kb/218185 for full list of LDAP error codes
const int ldapErrorInvalidCredentials = 0x31;

const string server = "sd.example.com:636";
const string domain = "sd.example.com";

try
{
    using (var ldapConnection = new LdapConnection(server))
    {
        var networkCredential = new NetworkCredential(_username, _password, domain);
        ldapConnection.SessionOptions.SecureSocketLayer = true;
        ldapConnection.AuthType = AuthType.Negotiate;
        ldapConnection.Bind(networkCredential);
    }

    // If the bind succeeds, the credentials are valid
    return true;
}
catch (LdapException ldapException)
{
    // Invalid credentials throw an exception with a specific error code
    if (ldapException.ErrorCode.Equals(ldapErrorInvalidCredentials))
    {
        return false;
    }

    throw;
}

I'm not thrilled with using a try/catch block to control decisioning logic, but it's what works. :/

like image 153
Nate Sauber Avatar answered Sep 20 '22 14:09

Nate Sauber