Active Directory COM异常 - 发生操作错误(0x80072020)

时间:2011-09-02 15:11:39

标签: c# .net exception com active-directory

当我尝试使用 GroupPrincipal.FindByIdentity方法查询Active Directory时,我收到间歇性的COM异常“发生操作错误(0x80072020)”(如下所示)强>

这是我的代码:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, Environment.UserDomainName);
GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "Group to find");

我收到例外:

Inner Exception: System.Runtime.InteropServices.COMException (0x80072020): An operations error occurred.
  at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  at System.DirectoryServices.DirectoryEntry.Bind()
  at System.DirectoryServices.DirectoryEntry.get_AdsObject()
  at System.DirectoryServices.PropertyValueCollection.PopulateList()
  at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
  at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
  at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
  at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
  at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
  at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
  at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
  at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
  at System.DirectoryServices.AccountManagement.GroupPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)

代码在 Windows 2003 SP2服务器上从 Windows服务运行。

我找到了另一个Stack Overflow问题,Active Directory, enumerating user's groups, COM exception,建议启用Kerberos 作为PrincipalContext构造函数中的选项将解决此问题,但我收到的是不同的十六进制代码而不是这个问题。

我的问题是

  1. 这个特定的COM Exception肯定是一个身份验证问题吗?我需要确保在发布软件之前,这将100%解决问题。
  2. 是否有某个资源列出了所有可能的COM异常十六进制代码,这样我将来可以更好地帮助自己?

8 个答案:

答案 0 :(得分:40)

问题通常是Active Directory调用的上下文是在没有权限的用户下(由于用户令牌的事实,也可能在ASP.NET中identity impersonate="true"时发生。是从“https://social.technet.microsoft.com/Forums/en-US/f188029c-51cf-4b50-966a-eee7160d0353/an-operations-error-occured”对另一台服务器进行身份验证时无法使用的“辅助令牌”。

以下代码将确保您运行的代码块在您的服务或网站运行的AppPool(即NETWORKSERVICE)的上下文中运行。

using (HostingEnvironment.Impersonate())
{
   var domainContext = new PrincipalContext(ContextType.Domain, "myDomain.com");
   var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.Name, "PowerUsers");
   if (groupPrincipal != null)
   {
      //code to get the infomation
   }

}

但是,一个非常重要的细节是所有调用Active Directory的代码必须在该块中。我使用了我的团队成员编写的一些代码,它返回LINQ类型为Users的查询结果(自定义类),但没有评估表达式(不良做法)。因此返回表达式树而不是结果。

最终发生的事情是调用代码最终评估了结果,An operations error occurred消息仍然出现。我虽然上面的代码修复不起作用。实际上它确实如此,但是有代码评估了块外的结果。

简而言之,确保访问Active Directory的所有代码位于using块内,并且应修复异常,将服务/应用程序部署到服务器。

答案 1 :(得分:19)

我现在找到了另一个答案Unable to add user with CrmService API in Dynamics CRM,其中指出0x80072020确实是一个权限问题。我已将服务更改为在域级帐户下运行而不是本地系统帐户,这似乎已经解决了我的问题。

答案 2 :(得分:9)

当然,这是2年后,我遇到了这个,发现以下问题解决了我的问题:

using System.Web.Hosting;
...
...
// Code here runs as the logged on user

using (HostingEnvironment.Impersonate()) {
// This code runs as the application pool user
     DirectorySearcher searcher ...
}

reference

答案 3 :(得分:4)

在ASP.NET(Windows 2008 R2 / IIS7)中发生了这种情况,我正在搞乱Web.config,并且每次FindByIdentity调用都会发生此错误。根本原因是App Pool作为DefaultAppPool运行,一旦我将其更改为以Network Service运行,它就再次开始工作。我不太明白为什么会改变它,但确实如此。

答案 4 :(得分:2)

我遇到了同样的问题。 我在更改应用程序池后获得了成功,如下所示:    流程模型       load user profile = true

答案 5 :(得分:0)

就我而言,网络应用程序池运行为" DefaultAppPool"没有足够的权限连接到公司的Active Directory。所以,我冒充了一个可以在我的代码中访问AD的帐户,一切正常。

答案 6 :(得分:0)

如果您收到错误代码,"发生了操作错误(0x80072020)" ,则可能意味着"访问被拒绝"

  • 检查您的Web服务器是否在AD域中
    • 如果不是,则必须将身份验证放入PrincipalContext。
示例(像这样):
public bool foo(String username, String password) {
    string ADIPaddress = "[ipaddress]";
    ContextOptions options = ContextOptions.Negotiate;
    PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, AD_IPaddress, null, options, username, password);
    bool isAuthenticated = principalContext.ValidateCredentials(username, password, options);
    return isAuthenticated;
}
参考

答案 7 :(得分:0)

对我来说,我遇到同样的问题,尝试登录其中一个域控制器,我有2个域控制器,其中一个正在工作,另一个不工作,我相信它与用户个人资料,仍在调查...