本文介绍了如何验证Active Directory的creds通过LDAP + SSL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用.NET 3.5 System.DirectoryServices.AccountManagement 命名空间通过SSL加密LDAP验证对我们的Active Directory LDAP服务器的用户凭据的连接。这里的样品code:

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);
}

这code正常工作,在不安全的LDAP(端口389),但我宁愿不以明文形式传输用户名/密码组合。但是,当我换到LDAP + SSL(端口636),我得到以下异常:

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)

端口636适用于其他活动,如查找无密码信息LDAP / AD进入...

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

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

...所以我知道这是不是我的LDAP服务器的SSL设置,因为它的工作原理基于SSL的其他查询。

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

有没有人得到的 ValidateCredentials(...)打电话给工作在SSL?你能解释一下?还是有另一种/更好的方法来安全地验证AD / LDAP凭证?

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?

推荐答案

我能够验证使用 System.DirectoryServices.Protocols 命名空间的凭据,得益于合作工人。这里的code:

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;
}

我不激动与使用try / catch块来控制的决策逻辑,但它是什么在起作用。 :/

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

这篇关于如何验证Active Directory的creds通过LDAP + SSL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 00:08