问题 LDAPS连接出现未知错误(0x80005000)


在烦人的Active Directory位上,我最近几个小时都被困住了。

我想要完成的是通过SSL上的LDAP连接到Active Directory。身份验证类型是匿名的。我正在使用.NET Framework 4.0,C#和Visual Studio 2010。

以下代码应根据各种在线资源工作。但它不断提出令人惊讶的不言自明:“未知错误(0x80005000)”。

DirectoryEntry entry = new DirectoryEntry();
entry.Path = "LDAPS://some.ldap.server:636";
entry.AuthenticationType = AuthenticationTypes.SecureSocketsLayer;

DirectorySearcher searcher = new DirectorySearcher();
searcher.searchRoot = entry;
searcher.Filter = "(&(objectCategory=person)(objectClass=user))";

SearchResultCollection results = searcher.FindAll();

我已经将我想要执行的实际查询简化为您在代码中找到的查询。但即使使用这种通用查询(它应该返回每个AD的工作?),它也会返回错误。


9179
2018-04-03 13:07


起源

The authentication type is anonymous。它不是,你将它设置为AuthenticationTypes.SecureSocketsLayer。它标识发件人,因此您最好设置用户名+密码。 - Hans Passant
嗨汉斯,我尝试使用名为的工具连接到AD JXplorer。设置为SSL并且未指定用户名或密码时,它工作正常。 - Rob Maas
那么,请注意球。指定有效用户时,您仍然可以获得E_FAIL吗?指定AuthenticationTypes.Anonymous时它是否有效?如果确实如此,则可以自由地假设JXplorer在没有指定用户时执行简单回退到Anonymous或使用登录用户凭据等操作。 - Hans Passant
Hans,我已经尝试过指定有效用户并指定AuthenticationTypes.Anonymous。仍然是相同的非描述性错误。还有其他任何诡计吗? - Rob Maas


答案:


最后!

似乎ASP.NET应用程序没有权限(或不知道如何)在机器级别检查受信任的证书存储。由于证书是自签名的,因此ASP.NET应用程序拒绝建立连接。

我使用自定义证书验证修复了问题。 以下代码可以解决问题:

LdapConnection con = new LdapConnection(new LdapDirectoryIdentifier("server", port));
con.SessionOptions.SecureSocketLayer = true;
con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(ServerCallback);
con.Credential = new NetworkCredential(String.Empty, String.Empty);
con.AuthType = AuthType.Basic;
con.Bind();

由于我确信证书有效,ServerCallBack方法如下所示:

public static bool ServerCallBack(LdapConnection connection, X509Certificate certificate)
{
    return true;
}

但是,您当然可以始终从本地计算机检索证书并对其进行验证。

此示例中使用的命名空间是:

System.DirectoryServices.Protocols;

这是因为命名空间:

System.DirectoryServices.DirectoryEntry

不包含自定义证书验证的方法。

谢谢大家的帮助和时间,希望这将有助于未来的人!


13
2018-04-11 13:49



+1,我还要为这里的任何人添加,确保你不需要信用卡连接到ldap服务器,因为你可能。此外,要查询ldap,您需要使用SearchRequest和SearchResponse类,而SearchResponse没有排序,因此您必须自己实现。我使用这不是自定义证书验证的b / c但是 DirectoryEntry 在WinPE中失败了,不知道为什么但这样做无论如何...... - MDMoore313
您可以通过打开机器商店的证书mmc管理单元授予asp.net权限以访问机器存储中的证书,找到要使用的证书,右键单击>任务>管理私钥并授予网络服务读取权限对。这对于使用证书的任何内容都很有用,例如Identity Foundation等 - Simon Halsey
我今天找到你的答案,我遇到了同样的问题。抛出的异常并不直观,并且很多时候找不到这个解决方案。这篇文章非常有用,+1或课程。 - h_s


据我所知,此错误表示目录路径名称存在问题。

  1. 确保“server.domainName”是AD服务器证书中的CN。
  2. 确保“some.domainName”得到很好的解析,在主机文件中添加分辨率以进行测试
  3. 确保“domainName”已得到很好的解析,在主机文件中添加分辨率以进行测试
  4. 确保颁发服务器证书的证书颁发机构的公共密钥位于计算机受信任的根证书颁发机构存储中。
  5. 尝试这样做:

DirectoryEntry entry = new DirectoryEntry("LDAPS://srventr2.societe.fr:636/DC=societe,DC=fr", "user", "password");

DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchRoot = entry;
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = "(&(objectCategory=person)(objectClass=user))";
SearchResultCollection results = searcher.FindAll(); 

2
2018-04-03 20:27



嗨,当我在同一台Windows服务器机器上运行代码时,代码可以正常运行;但我需要从远程机器使用DirectoryEntry;在这种情况下它不工作;我需要做的其他任何改变? - Dinesh Kumar P
“它不起作用”对我来说不足以帮助你。 - JPBlanc
道歉;我在远程计算机上运行相同的代码,并将“服务器无法运行”作为异常消息;我发现远程机器中没有验证寡妇服务器证书;要使用“LdapConnection”API验证证书,代码在此“帖子中,stackoverflow.com/questions/12621256/...;;我的要求是我需要验证证书并使用与您相同的“DirectoryEntry”API; - Dinesh Kumar P


根据您的目录服务器(或网络上的元素)的配置方式,有时可以进行简单的更改(LDAP与LDAPS,但保留端口号)

entry.Path = "LDAP://some.ldap.server:636";

1
2018-04-03 20:31



没有;它不起作用 - Dinesh Kumar P
它帮助了我但不确定导致这种行为的特定AD配置是什么。另外一个有趣的行为是,当你在URL中给出小写的ldap协议名称时它不起作用,即“LDAP://some.ldap.server:636”可以工作,但是“ldap://some.ldap.server” :636“没有。我特意吓坏了。 - RBT
它也适用于我没有将DirectoryEntry对象上的AuthenticationType属性设置为AuthenticationTypes.SecureSocketsLayer,但我不确定这是否会在所有环境和拓扑中保持一致。 - RBT