Je reçois une exception COM intermittente " Une erreur d'opération s'est produite (0x80072020) " (illustrée ci-dessous) lorsque j'essaie d'interroger Active Directory à l'aide de la méthode - GroupPrincipal.FindByIdentity
Voici mon code:
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, Environment.UserDomainName);
GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "Group to find");
Je reçois une exception:
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)
Le code s'exécute à partir d'un service Windows sur un serveur Windows 2003 SP2 .
J'ai trouvé une autre question de débordement de pile, Active Directory, énumération des groupes d'utilisateurs, exception COM , suggérant que l'activation de Kerberos comme option dans le constructeur PrincipalContext corrigera ce problème mais je reçois un code hex différent que dans cette question.
Mes questions sont :
J'ai maintenant trouvé une autre réponse Impossible d'ajouter l'utilisateur avec l'API CrmService dans Dynamics CRM qui indique que 0x80072020 est en effet un problème d'autorisation. J'ai changé mon service pour qu'il fonctionne sous un compte au niveau du domaine au lieu du compte système local et cela semble avoir résolu mon problème.
Le problème est souvent que le contexte pour lequel les appels Active Directory sont effectués est sous un utilisateur qui n'a pas d'autorisations (peut également se produire lorsque identity impersonate="true"
dans ASP.NET, car le jeton des utilisateurs est un "jeton secondaire" qui ne peut pas être utilisé lors de l'authentification sur un autre serveur à partir de: https://social.technet.Microsoft.com/Forums/ en-US/f188029c-51cf-4b50-966a-eee7160d0353/an-operations-error-occurrence ).
Le code suivant garantit que le bloc de code que vous exécutez est exécuté dans le contexte, par exemple, du AppPool
(c'est-à-dire NETWORKSERVICE
) sous lequel votre service ou site s'exécute.
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
}
}
Cependant, un détail super important est que tout le code appelant Active Directory doit être dans ce bloc. J'avais utilisé du code écrit par un membre de mon équipe qui renvoyait une LINQ
résultats de requête de type Users
(classe personnalisée), mais sans évaluer l'expression (mauvaise pratique). Par conséquent, l'arborescence d'expression a été renvoyée au lieu des résultats.
En fin de compte, le code appelant a finalement évalué les résultats et le An operations error occurred
le message est toujours apparu. Je pensais que le correctif de code ci-dessus ne fonctionnait pas. Alors qu'en fait, mais il y avait du code évaluant les résultats en dehors du bloc.
En un mot, assurez-vous que tout le code pour accéder à Active Directory se trouve dans ce bloc using
et l'exception doit être corrigée dans le service/l'application est déployée sur le serveur.
Certes, c'est 2 ans plus tard, je suis tombé sur cela et j'ai constaté que ce qui suit avait résolu mon problème:
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 ...
}
Cela m'est arrivé dans ASP.NET (Windows 2008 R2/IIS7) où je jouais avec Web.config et cette erreur a commencé à se produire à chaque appel FindByIdentity. La cause principale était que le pool d'applications s'exécutait en tant que DefaultAppPool, et il a recommencé à fonctionner une fois que je l'ai modifié pour fonctionner en tant que service réseau. Je ne comprends pas très bien pourquoi cela changerait, mais c'est le cas.
J'ai eu le même problème. J'ai réussi après avoir changé le pool d'applications comme ci-dessous: Profil utilisateur de chargement du modèle de processus = true
Si vous obtenez un code d'erreur, "Une erreur d'opération s'est produite (0x80072020)" , cela peut signifier "Accès refusé ".
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;
}
Pour moi, j'ai rencontré le même problème en essayant de me connecter à l'un des contrôleurs de domaine, j'ai 2 contrôleurs de domaine, 1 d'entre eux fonctionne et l'autre ne fonctionne pas, je crois que cela a quelque chose à voir avec le profil utilisateur, enquête toujours ...
Dans mon cas, le pool d'applications Web s'exécutait en tant que "DefaultAppPool" qui n'avait pas un accès suffisant pour se connecter à Active Directory de la société. J'ai donc emprunté un compte qui a accès à AD dans mon code et tout a bien fonctionné.