2010-08-04 4 views
9

Je rencontre un problème lors de l'utilisation de la méthode GetAuthorizationGroups de la classe UserPrincipal dans une application Web.Erreur avec la méthode UserPrincipal.GetAuthorizationGroups()

En utilisant le code suivant, je reçois « Tout en essayant de récupérer les groupes d'autorisation, une erreur (5) a été observée »

PrincipalContext context = new PrincipalContext(ContextType.Domain, null, "DC=MyCompany,DC=COM", "username", "password"); 
UserPrincipal p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "joe.blogs"); 
var groups = p.GetAuthorizationGroups(); 

Je crois que ce code fonctionne dans une certaine mesure.

  • Quand je regarde l'objet de contexte, je peux voir le serveur et le nom d'utilisateur/mot de passe ont été résolus correctement dans l'objet
  • Quand je regarde l'objet p, je peux voir les détails AD ont été renseignés comme le téléphone ne

Voici la trace de la pile de l'erreur.

[PrincipalOperationException: While trying to retrieve the authorization groups, an error (5) occurred.] 
    System.DirectoryServices.AccountManagement.AuthZSet..ctor(Byte[] userSid, NetCred credentials, ContextOptions contextOptions, String flatUserAuthority, StoreCtx userStoreCtx, Object userCtxBase) +317279 
    System.DirectoryServices.AccountManagement.ADStoreCtx.GetGroupsMemberOfAZ(Principal p) +441 
    System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroupsHelper() +78 
    System.DirectoryServices.AccountManagement.UserPrincipal.GetAuthorizationGroups() +11 

En supprimant les détails du nom d'utilisateur et mot de passe du constructeur PrincipalContext et changer la ApplicationPool (en IIS7) pour exécuter le même utilisateur ([email protected]) - le code suivant fonctionne.

PrincipalContext context = new PrincipalContext(ContextType.Domain, null, "DC=MyCompany,DC=COM"); 
UserPrincipal p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "joe.blogs"); 
var groups = p.GetAuthorizationGroups(); 

J'ai besoin d'obtenir le code dans le premier exemple au travail - je ne veux pas courir le pool d'applications en tant qu'utilisateur de domaine juste pour obtenir ce code de travail.

Répondre

2

L'erreur 5 indique ERROR_ACCESS_DENIED, ce qui suggère un problème lié aux autorisations. Cela dit, le code suivant vient travaillé pour moi, en cours d'exécution sur Windows 7 avec le site Web en cours d'exécution que le pool d'applications par défaut:

Contenu du "corps" de .aspx page:

<asp:GridView ID="GridView1" runat="server"> 
</asp:GridView> 

code-behind :

protected void Page_Load(object sender, EventArgs e) 
{ 
    var Context = new PrincipalContext(ContextType.Domain, "logon_domain", "username", "password"); 
    var principal = UserPrincipal.FindByIdentity(Context, "user_to_query"); 
    var groups = principal.GetAuthorizationGroups(); 

    GridView1.DataSource = groups; 
    GridView1.DataBind(); 
} 

Dans mon exemple logon_domain était la gauche de domain_name\username, plutôt que le style de spécification de domaine que vous utilisez. Ma solution peut ou peut ne pas fonctionner pour vous. Si ce n'est pas le cas, cela indique un problème d'autorisations quelque part.

+0

Merci Rob, j'ai essayé plusieurs combinaisons dans le constructeur PrincipalContext sans avoir de chance. Je pense que la cause première de mon problème est de connaître les conditions d'autorisation de l'utilisateur de l'application pour appeler la méthode GetAuthorizationGroups(). Mon utilisateur d'application a lu tous les droits d'informations sur les objets dans l'unité d'organisation. Actuellement, je fais cela le long chemin en lisant la propriété memberOf des utilisateurs. Ce howerver n'est que le premier niveau et non récursif. –

+0

FWIW, j'avais une version de travail où j'ai utilisé 'var Context = new PrincipalContext (ContextType.Domain, "logon_domain"); ', donc le contexte était purement un domaine et qui a également travaillé sans erreur dans Win7/pool d'applications par défaut. La machine sur laquelle vous exécutez votre code est-elle connectée au domaine? – Rob

+1

Oui, joint à un domaine. Si j'utilise le constructeur PrincipalContext (ContextType.Domain, "logon_domain") avec le service réseau (AppPool), cela ne fonctionne pas. Si je change l'AppPool pour s'exécuter comme le même utilisateur que celui utilisé dans la méthode PrincipalContext (ContextType.Domain, null, "DC = MonCompagnie, DC = COM", "nom d'utilisateur", "mot de passe") cela fonctionne! –

5

J'ai traité ce même problème. Voir la discussion sur une question similaire. https://stackoverflow.com/a/8347817/2012977

solution est ci-dessous:

public List<GroupPrincipal> GetGroups(string userName) 
    { 
     var result = new List<GroupPrincipal>(); 
     PrincipalContext ctx = GetContext(); /*function to get domain context*/ 
     UserPrincipal user = UserPrincipal.FindByIdentity(ctx, userName); 
     if (user != null) 
     { 
      PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups(); 

      var iterGroup = groups.GetEnumerator(); 
      using (iterGroup) 
      { 
       while (iterGroup.MoveNext()) 
       { 
        try 
        { 
         Principal p = iterGroup.Current; 
         result.Add((GroupPrincipal) p); 
        } 
        catch (PrincipalOperationException) 
        { 
         continue; 
        } 
       } 
      } 
     } 

     return result; 
    } 
0

Demandez à votre regard d'administrateur au compte AD pour l'utilisateur qui renvoie le code d'erreur 5. Je suis tombé sur aujourd'hui et il est avéré être de un paramètre sur cet utilisateur Compte. Une case à cocher pour hériter des paramètres de sécurité n'a pas été cochée (tous les autres utilisateurs ont été cochés). Cela a résolu pour moi.