C# LDAPS 连接出现未知错误 (0x80005000)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9993928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unknown Error (0x80005000) with LDAPS Connection
提问by Rob Maas
I've been stuck for the last couple of hours on an annoying Active Directory bit.
在过去的几个小时里,我一直被一个烦人的 Active Directory 问题困住了。
What I'm trying to accomplish is connect to an Active Directory via LDAP over SSL. The authentication type is anonymous. I'm using .NET Framework 4.0, C# and Visual Studio 2010.
我想要完成的是通过 SSL 上的 LDAP 连接到 Active Directory。身份验证类型是匿名的。我正在使用 .NET Framework 4.0、C# 和 Visual Studio 2010。
The following code should work according to various online resources. But it keeps coming up with the amazing self-explanatory: 'Unknown Error (0x80005000)'.
以下代码应根据各种在线资源工作。但它不断提出惊人的不言自明:“未知错误(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();
I've simplified the actual query I want to perform to the one you find in the code. But even with this generic query (it should return work on every AD?) it returns the error.
我已将要执行的实际查询简化为您在代码中找到的查询。但即使使用这个通用查询(它应该在每个 AD 上返回工作?)它也会返回错误。
采纳答案by Rob Maas
Finally!
最后!
It seems that an ASP.NET application does not have the rights (or doesn't know how) to examine the trusted certificate store at machine level. Since the certificate was self-signed the ASP.NET application refused to establish a connection.
ASP.NET 应用程序似乎无权(或不知道如何)在机器级别检查受信任的证书存储。由于证书是自签名的,ASP.NET 应用程序拒绝建立连接。
I fixed the problem using custom certificate validation. The following code did the trick:
我使用自定义证书验证解决了这个问题。以下代码成功了:
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();
Since I am sure the certificate is valid, the ServerCallBack method looks like this:
由于我确定证书有效,因此 ServerCallBack 方法如下所示:
public static bool ServerCallBack(LdapConnection connection, X509Certificate certificate)
{
return true;
}
But you can always of course retrieve the certificate from the local machine and validate it.
但是您当然可以从本地机器检索证书并对其进行验证。
The namespace used in this example is:
本例中使用的命名空间是:
System.DirectoryServices.Protocols;
This is because the namespace:
这是因为命名空间:
System.DirectoryServices.DirectoryEntry
does not contain a method for custom certificate validation.
不包含自定义证书验证方法。
Thank you all for your help and time, and hopefully this will help someone in the future!
感谢大家的帮助和时间,希望这会对未来的人有所帮助!
回答by JPBlanc
As far as I remember This error means that there is a problem with the directory path name.
据我记得这个错误是指目录路径名有问题。
- Be sure that "server.domainName" is the CN in the certificate of your AD server.
- Be sure that "some.domainName" is well resolved add the resolution in your hosts file for the test
- Be sure that the "domainName" is well resolved add the resolution in your hosts file for the test
- Be sure that the public ke of the certificate authority that issue the server certificate is in your computer trusted root certification authority store.
- try doing like this :
- 请确保“server.domainName”是您的 AD 服务器证书中的 CN。
- 确保“some.domainName”得到很好的解析,在您的主机文件中添加分辨率以进行测试
- 确保“domainName”得到很好的解析,在您的主机文件中添加解析以进行测试
- 请确保颁发服务器证书的证书颁发机构的公钥位于您的计算机受信任的根证书颁发机构存储中。
- 尝试这样做:
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();
回答by curtisk
Depending on how your directory server(or elements on your network are configured) sometimes a simple change such as this will work (LDAP vs. LDAPS, but leave port number)
根据您的目录服务器(或网络上的元素的配置方式),有时这样的简单更改会起作用(LDAP 与 LDAPS,但保留端口号)
entry.Path = "LDAP://some.ldap.server:636";

