52

我正在尝试使用 .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 服务的一部分运行时(在相同的凭据下运行),它会引发上述异常。

有什么建议么?

谢谢

4

13 回答 13

126

我一次又一次地遇到同样的情况,似乎没有任何帮助。

将路径从 更改ldap://LDAP://成功了。

于 2012-04-11T06:55:44.583 回答
37

这是一个权限问题。

当您运行控制台应用程序时,该应用程序将使用您的凭据运行,例如“您”。

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从搜索结果中获取完整(应该更快),并且由于你告诉目录搜索器找到该属性,它肯定会被加载到搜索结果中 - 所以除非它为空(未设置值),那么您应该能够轻松检索它。

马克

于 2009-11-12T14:07:32.327 回答
22

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

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

在此处输入图像描述

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

于 2014-07-01T01:02:28.763 回答
15

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

于 2017-12-20T18:31:54.220 回答
13

我有同样的错误 - 在我的情况下,路径参数中的额外斜杠造成了差异。

坏的:

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

好的:

DirectoryEntry directoryEntry = 
    new DirectoryEntry("LDAP://someserver.contoso.com/DC=contoso,DC=com", 
                       userName, password);
于 2015-01-22T14:42:40.727 回答
9

我也遇到了这个错误,对我来说,这是一个名称中带有正斜杠的 OU:“文件/文件夹访问组”。

论坛主题为我指明了正确的方向。最后,在使用前调用.Replace("/","\\/")每个路径值为我解决了这个问题。

于 2011-11-23T19:55:07.853 回答
3

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

我得到了完全相同的错误信息和代码

于 2011-03-12T17:29:45.957 回答
3

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

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

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

问候, 阿卡西奥

于 2015-07-14T09:02:59.850 回答
1

如果物理机内存不足,则会发生此错误。就我而言,我在 IIS 上托管了一个站点,试图访问 AD,但服务器内存不足。

于 2017-06-23T10:57:37.097 回答
1

我不得不改变我的代码:

 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();
于 2020-11-18T00:30:25.193 回答
1

当我查询福雷斯特的另一个域的条目并且该条目具有另一个域的一些自定义属性时,我遇到了这个错误。

要解决这个错误,我只需要在 url LDAP 中指定服务器:

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

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

于 2020-11-19T14:37:27.353 回答
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); 
          }        
     }
}
于 2016-03-02T06:28:11.350 回答
0

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

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

于 2017-06-09T17:13:27.513 回答