我正在尝试使用.NET 3.5 System.DirectoryServices.AccountManagement
命名空间来验证针对我们的Active Directory LDAP服务器 over an SSL encrypted LDAP connection 的用户凭据 . 这是示例代码:
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凭据?
4 回答
感谢一位同事,我能够使用
System.DirectoryServices.Protocols
命名空间验证凭据 . 这是代码:我对使用try / catch块来控制决策逻辑感到很兴奋,但它的作用是什么 . :/
也许这是另一种方式 . 验证凭据中没有任何异常 . ContextOptions必须正确设置 .
默认值:
添加Ssl:
ContextOptions.Negotiate或ContextOptions.SimpleBind是必需的 . 或者服务器执行身份验证所需的任何内容ContextOptions仅支持OR位 .
您也可以尝试在ValidateCredentials方法中以这种方式直接设置ContextOptions .
要么
对我来说,ValidateCredentials方法工作得很好 . 我发现问题出在托管AD的服务器上(我正在使用AD LDS) . 您需要将服务器证书与AD实例相关联 . 因此,如果您的实例名为“MyAD”(或ActiveDirectoryWebService),则需要打开MMC,在“证书”模块中单击,选择“服务帐户”,然后从列表中选择“MyAD” . 从那里,您可以将SSL证书添加到“MyAD”个人存储中 . 这终于将SSL处理推向了极致 .
我怀疑,根据我所知道的 LdapConnection 方法以及您省略了回调函数的事实,您没有验证您的服务器证书 . 这是一个麻烦的工作, ValidateCredentials 是免费的 . 可能不是什么大不了的事,但却是一个安全漏洞 .
我知道这是旧的,但对于任何遇到这种情况的人来说:
PrincipalContext.ValidateCredentials(...)
,默认情况下,尝试打开SSL连接(ldap_init(NULL, 636)
),然后设置选项LDAP_OPT_FAST_CONCURRENT_BIND
.但是,如果存在(受信任的?) client certificate ,则会隐式绑定LDAP连接,并且不再启用快速绑定 . PrincipalContext不考虑这种情况,并且因意外
DirectoryOperationException
而失败 .Workaround: 要尽可能支持SSL,但要有后备,请先使用默认选项调用
ValidateCredentials(...)
(即无选项) . 如果使用DirectoryOperationException
失败,请再次指定ContextOptions
(Negotiate | Sealing | Signing),这是ValidateCredentials
内部为预期的LdapException
做的事情 .