当我尝试使用 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 构造函数中的一个选项将解决此问题,但我收到了一个与此问题不同的十六进制代码。
我的问题是:
- 这个特殊的 COM 异常是否确实是身份验证问题?在发布软件之前,我需要确保这将 100% 解决问题。
- 是否有某个资源列出了所有可能的 COM 异常十六进制代码,以便我以后可以更好地帮助自己?
最佳答案
问题通常是 Active Directory 调用所针对的上下文是在没有权限的用户下(也可能发生在 ASP.NET 中的 identity impersonate="true"
时,由于用户 token 是“辅助 token ”,在对另一台服务器进行身份验证时无法使用: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 的代码 都必须在该 block 中。我使用了我的团队成员编写的一些代码,该代码返回类型为 Users
(自定义类)的 LINQ
查询结果,但不评估表达式(不良做法)。因此返回表达式树而不是结果。
最终发生的事情是调用代码最终评估了结果,并且 发生操作错误
消息仍然出现。我虽然上面的代码修复不起作用。事实上确实如此,但有代码在 block 外评估结果。
简而言之,确保访问 Active Directory 的所有代码都在 using
block 中,并且在服务/应用程序部署到服务器时应该修复异常.
关于c# - Active Directory COM 异常 - 发生操作错误 (0x80072020),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7285503/