如何通过LDAP + SSL验证Active Directory信誉?

Nat*_*ber 15 .net c# directoryservices ldap active-directory

我正在尝试使用.NET 3.5 System.DirectoryServices.AccountManagement命名空间通过SSL加密的LDAP连接验证针对我们的Active Directory LDAP服务器的用户凭据.这是示例代码:

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

此代码在不安全的LDAP(端口389)上工作正常,但我宁愿不以明文形式传输用户/传递组合.但是,当我更改为LDAP + SSL(端口636)时,我得到以下异常:

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)
Run Code Online (Sandbox Code Playgroud)

端口636适用于其他活动,例如查找该LDAP/AD条目的非密码信息...

UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, _username)
Run Code Online (Sandbox Code Playgroud)

...所以我知道这不是我的LDAP服务器的SSL设置,因为它适用于其他查找的SSL.

有没有人接到ValidateCredentials(...)通过SSL工作的电话?你能解释一下吗?或者是否有另一种/更好的方法可以安全地验证AD/LDAP凭据?

Nat*_*ber 14

System.DirectoryServices.Protocols由于一位同事,我能够使用命名空间验证凭据.这是代码:

// 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;
}
Run Code Online (Sandbox Code Playgroud)

我对使用try/catch块来控制决策逻辑感到非常兴奋,但它才有效.:/