错误0x80005000和DirectoryServices

时间:2009-11-12 14:03:58

标签: c# .net wcf active-directory directoryservices

我正在尝试使用.Net中的目录服务运行简单的LDAP查询。

    DirectoryEntry directoryEntry = new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com");
    directoryEntry.AuthenticationType = AuthenticationTypes.Secure;

    DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);

    directorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", username);

    var result = directorySearcher.FindOne();
    var resultDirectoryEntry = result.GetDirectoryEntry();

    return resultDirectoryEntry.Properties["msRTCSIP-PrimaryUserAddress"].Value.ToString();

我得到以下例外:

System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)
  at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  at System.DirectoryServices.DirectoryEntry.Bind()
  at System.DirectoryServices.DirectoryEntry.get_AdsObject()
  at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
  at System.DirectoryServices.DirectorySearcher.FindOne()

作为控制台应用中的代码段,这是有效的。但是当我将它作为WCF服务的一部分运行(在相同的凭据下运行)时,它会抛出上述异常。

有什么建议吗?

由于

13 个答案:

答案 0 :(得分:86)

我一次又一次地拥有同样的东西,似乎没有任何帮助。

将路径从ldap://更改为LDAP://就可以了。

答案 1 :(得分:31)

这是一个许可问题。

当您运行控制台应用时,该应用会使用您的凭据运行,例如作为“你”。

WCF服务在哪里运行?在IIS?最有可能的是,它在一个单独的帐户下运行,该帐户无权查询Active Directory。

您可以尝试让WCF模拟工作正常,以便传递您自己的凭据,或者您可以在创建DirectoryEntry时指定用户名/密码:

DirectoryEntry directoryEntry = 
    new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com", 
                       userName, password);

好的,所以它可能不是凭证(在我看到的80%以上的案例中通常就是这种情况)。

如何更改代码呢?

DirectorySearcher directorySearcher = new DirectorySearcher(directoryEntry);
directorySearcher.Filter = string.Format("(&(objectClass=user)(objectCategory=user) (sAMAccountName={0}))", username);

directorySearcher.PropertiesToLoad.Add("msRTCSIP-PrimaryUserAddress");

var result = directorySearcher.FindOne();

if(result != null)
{
   if(result.Properties["msRTCSIP-PrimaryUserAddress"] != null)
   {
      var resultValue = result.Properties["msRTCSIP-PrimaryUserAddress"][0];
   }
}

我的想法是:为什么不直接告诉DirectorySearcher你感兴趣的属性是什么?然后你不需要再做一个额外的步骤来从搜索结果中获取完整的DirectoryEntry(应该更快),并且因为你告诉目录搜索者找到那个属性,它肯定会被加载到搜索结果 - 所以除非它是null(没有设置值),否则你应该能够轻松地检索它。

马克

答案 2 :(得分:16)

在Ektron的上下文中,通过在Windows中安装“IIS6元数据库兼容性”功能解决了此问题:

  

检查IIS6 Metabase的“Windows功能”或“角色服务”   兼容性,如果缺少则添加:

enter image description here

参考:https://portal.ektron.com/KB/1088/

答案 3 :(得分:10)

我有同样的错误 - 在我的情况下,它是路径参数中的额外斜杠,它产生了不同。

BAD:

DirectoryEntry directoryEntry = 
    new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com/", 
                       userName, password);

GOOD:

DirectoryEntry directoryEntry = 
    new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com", 
                       userName, password);

答案 4 :(得分:7)

我也有这个错误,对我来说,这是一个名为“文件/文件夹访问组”的正斜杠的OU。

forum thread指出了正确的方向。最后,在使用前在每个路径值上调用.Replace("/","\\/")解决了我的问题。

答案 5 :(得分:5)

在IIS托管网站上,尝试回收应用池。它解决了我的问题。 感谢

答案 6 :(得分:3)

仅供参考,我遇到了同样的错误并使用了正确的凭据但我的LDAP网址错误:(

我收到完全相同的错误消息和代码

答案 7 :(得分:3)

在我居住的公司的生产系统中遇到了这个问题...在IP更改后,使LDAP绑定停止工作的网页。

解决方案...... ...我安装了基本身份验证以执行此处指示的问题排查:https://support.microsoft.com/en-us/kb/329986

在那之后,事情开始发挥作用。即使在我测试的页面中重新禁用基本身份验证之后,所有其他页面也开始使用Windows身份验证。

此致 Acácio

答案 8 :(得分:1)

如果物理机内存不足,则可能发生此错误。 在我的情况下,我在IIS上托管一个试图访问AD的站点,但是服务器内存不足。

答案 9 :(得分:0)

如果在DirectoryEntry.Patch中符号“LDAP //:”后面没有任何内容,则会发生同样的错误。有必要在directorySearcher.FindOne()之前检查directoryEntry.Path。除非明确指定域,否则不需要“LDAP://”。

private void GetUser(string userName, string domainName)
{
     DirectoryEntry dirEntry = new DirectoryEntry();

     if (domainName.Length > 0)
     {
          dirEntry.Path = "LDAP://" + domainName;
     }

     DirectorySearcher dirSearcher = new DirectorySearcher(dirEntry);
     dirSearcher.SearchScope = SearchScope.Subtree;
     dirSearcher.Filter = string.Format("(&(objectClass=user)(|(cn={0})(sn={0}*)(givenName={0})(sAMAccountName={0}*)))", userName);
     var searchResults = dirSearcher.FindAll();
     //var searchResults = dirSearcher.FindOne();

     if (searchResults.Count == 0)
     {
          MessageBox.Show("User not found");
     }
     else
     {
          foreach (SearchResult sr in searchResults)
          {
              var de = sr.GetDirectoryEntry();
              string user = de.Properties["SAMAccountName"][0].ToString();
              MessageBox.Show(user); 
          }        
     }
}

答案 10 :(得分:0)

在我的类似问题上花了一天时间,但所有这些答案都没有用。

在我的情况下,我没有在IIS设置中启用Windows身份验证...

答案 11 :(得分:0)

我必须从此更改代码:

 DirectoryEntry entry = new DirectoryEntry(path, ldapUser, ldapPassword);
 DirectorySearcher searcher = new DirectorySearcher();
 searcher.SearchRoot = entry;
 searcher.SearchScope = SearchScope.Subtree;

对此:

DirectoryEntry entry = new DirectoryEntry(path, ldapUser, ldapPassword);
DirectorySearcher searcher = new DirectorySearcher();
searcher.SearchScope = SearchScope.OneLevel;
SearchResult searchResult = searcher.FindOne();

答案 12 :(得分:0)

查询forrest的另一个域的条目时遇到此错误,并且该条目具有另一个域的一些自定义属性。

要解决此错误,我只需要在URL LDAP中指定服务器:

错误= LDAP://CN=MyObj,DC=DOMAIN,DC=COM的路径

没有错误的路径:LDAP://domain.com:389/CN=MyObj,DC=Domain,DC=COM