【问题标题】:Error 0x80005000 and DirectoryServices错误 0x80005000 和 DirectoryServices
【发布时间】:2010-12-15 21:30:38
【问题描述】:

我正在尝试使用 .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()

作为控制台应用程序中的 sn-p,这是可行的。但是当我将它作为 WCF 服务的一部分运行(在相同的凭据下运行)时,它会引发上述异常。

有什么建议吗?

谢谢

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 这也为我修复了它。 LDAP 必须大写。
    • 对我来说很好的答案。特别是在使用 powershell 时,您不习惯区分大小写
    • WAAAAAAAAT??!我在这个 LDAP 上花了 2 小时后解决了我的问题!
    • 不是所有与 MS/Windows 相关的资源都应该不区分大小写吗?谢谢。
    【解决方案2】:

    这是一个权限问题。

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

    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(没有设置值),那么你应该能够轻松地检索它。

    马克

    【讨论】:

    • 我已以服务帐户身份登录到运行此进程的服务器,我已将 WCF 服务配置为运行 - 所以他们肯定使用相同的凭据吗?
    • 好的 - 您可以单步执行代码(或写出跟踪消息)以找出异常发生的确切位置吗??
    • 0x80005000 是一个漂亮的“样板”错误,可能意味着任何事情......
    【解决方案3】:

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

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

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

    【讨论】:

    • 对于我的具体问题(遇到 OP 错误,但我要使用 IIS,而不是 LDAP),这解决了它。谢谢
    【解决方案4】:

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

    【讨论】:

    • 这为我修好了!谢谢。
    • 酷,很高兴你成功了。事情并不总是我们有机会进行代码更改来解决这样的问题,特别是当我们不拥有或没有代码时,所以尝试这样的事情很有帮助:)。
    • 如果您使用实际用户帐户作为应用程序池身份而不是服务帐户:在应用程序池的高级设置中,将“加载用户配置文件”设置为 True。如果设置为 False,则当该用户注销计算机时,COM 操作所需的注册表项将不可用。
    • 啊!!!这是我的问题!这个答案应该更高,为我解决了这个问题。
    【解决方案5】:

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

    不好:

    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);
    

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

      • 非常感谢,这是我的问题!在尝试了 2 天的访问权限后,我们发现创建了一个名称中带有斜线的 OU。
      • 天啊谢谢@Nick
      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

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

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

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

        问候, 阿卡西奥

        【讨论】:

          【解决方案9】:

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

          【讨论】:

            【解决方案10】:

            我不得不改变我的代码:

             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();
            

            【讨论】:

              【解决方案11】:

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

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

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

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

              【讨论】:

                【解决方案12】:

                如果在 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); 
                          }        
                     }
                }
                

                【讨论】:

                  【解决方案13】:

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

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

                  【讨论】:

                  • 如果您需要恢复到应用程序池用户,您可以通过为 AD 调用“模拟”来做到这一点: using (WindowsIdentity.Impersonate(IntPtr.Zero)) { /* AD-Access * / }
                  猜你喜欢
                  • 1970-01-01
                  • 2021-03-08
                  • 2016-12-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-02-18
                  • 1970-01-01
                  相关资源
                  最近更新 更多