c# - 如何通过 LDAP + SSL 验证 Active Directory 凭据?

标签 c# .net active-directory ldap directoryservices

我正在尝试使用 .NET 3.5 System.DirectoryServices.AccountManagement 命名空间根据我们的 Active Directory LDAP 服务器通过 SSL 加密的 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);
}

此代码在不安全的 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)

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

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

...所以我知道这不是我的 LDAP 服务器的 SSL 设置,因为它通过 SSL 进行其他查找。

有没有人通过 SSL 获得 ValidateCredentials(...) 调用?你能解释一下吗?或者是否有另一种/更好的方法来安全地验证 AD/LDAP 凭据?

最佳答案

感谢同事,我能够使用 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;
}

我对使用 try/catch block 来控制决策逻辑并不感到兴奋,但它确实有效。 :/

关于c# - 如何通过 LDAP + SSL 验证 Active Directory 凭据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10850860/

相关文章:

active-directory - 如何在 C# 中读取 msExchMailboxSecurityDescriptor 属性

c# - 在 Wpf 和 WinForms 上使用 StreamSocket

c# - 如何对 ViewModel 消费方法进行单元测试?

c# - 添加 "winmd"引用与添加项目引用

asp.net - 增加 IIS7 中 Web 服务的最大并发连接数(负载测试)

java ldap - 获取信息是 AD 中的一些变化

c# - 使用 DHCP 从 IP 获取 mac 地址?

c# - 如何判断进程是否具有图形界面?

c# - 使用 Entity Framework 的最小存储库实现

c# - 如何使用 C# 表达式树创建 LINQ 友好的 'return false' 表达式?