当我尝试使用 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构造函数中的选项将解决此问题,但我收到的是不同的十六进制代码而不是这个问题。
我的问题是:
答案 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 ...
}
答案 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)" ,则可能意味着"访问被拒绝" 强>
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个域控制器,其中一个正在工作,另一个不工作,我相信它与用户个人资料,仍在调查...