web-dev-qa-db-fra.com

Exception COM Active Directory - Une erreur d'opération s'est produite (0x80072020)

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 :

  1. Cette exception COM particulière est-elle définitivement un problème d'authentification? Je dois être sûr que cela résoudra à 100% le problème avant de publier le logiciel.
  2. Existe-t-il une ressource quelque part qui répertorie tous les codes hexa d'exception COM possibles afin que je puisse m'aider un peu mieux à l'avenir?
27
ghostJago

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.

19
ghostJago

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.

41
atconway

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 ...
}

référence

9
Jake1164

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.

4
NightShovel

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

2
jose comar

Si vous obtenez un code d'erreur, "Une erreur d'opération s'est produite (0x80072020)" , cela peut signifier "Accès refusé ".

  • Vérifiez votre serveur Web dans le domaine AD ou non
    • Sinon, vous devez mettre l'authentification dans 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;
}
0
Angus Wu

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 ...

0
NanoHead

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é.

0
Arshad Mohammad