2010-08-04 22 views
9

Tengo un problema al usar el método GetAuthorizationGroups de la clase UserPrincipal en una aplicación web.Error con el método UserPrincipal.GetAuthorizationGroups()

Usando el siguiente código, que estoy recibiendo "Al tratar de recuperar los grupos de autorización, un error (5) se produjeron"

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(); 

Creo que este código funciona hasta cierto punto.

  • Cuando veo el objeto de contexto, puedo ver el servidor y el nombre de usuario/contraseña se han resuelto correctamente en el objeto
  • Cuando veo el objeto p, puedo ver los detalles del anuncio han sido pobladas como el teléfono sin etc.

Aquí está el seguimiento de la pila del error.

[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 

Al eliminar el nombre de usuario y la contraseña desde el constructor PrincipalContext y cambiando la ApplicationPool (en iis7) para ejecutar como el mismo usuario ([email protected]) - el código siguiente funciona.

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

necesito para obtener el código en el primer ejemplo de trabajar - No quiero ejecutar el grupo de aplicaciones como un usuario de dominio sólo para obtener el código de trabajo.

Respuesta

2

El error 5 indica ERROR_ACCESS_DENIED, lo que sugiere un problema relacionado con los permisos. Dicho esto, el código siguiente justo ha trabajado para mí, que se ejecuta en Windows 7 con el sitio web funcionando como el grupo de aplicaciones predeterminado:

contenido de "cuerpo" de la página .aspx:

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

de código subyacente :

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(); 
} 

En mi ejemplo logon_domain fue la izquierda de domain_name\username, más que el estilo de especificación de dominio hubiera utilizado. Mi solución puede o no funcionar para usted. Si no lo hace, apunta a un problema de permisos en alguna parte.

+0

Gracias Rob, he intentado muchas combinaciones en el constructor de PrincipalContext sin mucha suerte. Creo que la causa de mi problema es conocer los requisitos de permiso del usuario de la aplicación para invocar el método GetAuthorizationGroups(). Mi usuario de la aplicación ha leído todos los derechos de información sobre los objetos en la unidad organizativa. Actualmente estoy haciendo esto por mucho leyendo la propiedad memberOf de los usuarios. Este howerver es solo el primer nivel y no recursivo. –

+0

FWIW, tenía una versión en funcionamiento en la que usaba 'var Context = new PrincipalContext (ContextType.Dominio, "logon_domain"); ', por lo que el contexto era puramente de dominio y que también funcionaba sin error en Win7/grupo de aplicaciones predeterminado. ¿Se ha unido la máquina con la que está ejecutando su código en el dominio? – Rob

+1

Sí, unido a un dominio. si uso el constructor PrincipalContext (ContextType.Domain, "logon_domain") con el servicio de red (AppPool) no funciona. Si cambio AppPool para que se ejecute como el mismo usuario que usé en el método PrincipalContext (ContextType.Domain, null, "DC = MyCompany, DC = COM", "username", "password") ¡funciona! –

5

He tratado este mismo problema. Ver discusión sobre una pregunta similar. https://stackoverflow.com/a/8347817/2012977

solución es a continuación:

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

Haga que su administrador de la cuenta de AD para el usuario que devuelve el código de error 5. me encontré con que hoy en día y que resultó ser un entorno en que el usuario de cuenta. Hay una casilla de verificación para heredar la configuración de seguridad que no fue marcada (todos los demás usuarios fueron marcados). Esto lo resolvió para mí.

Cuestiones relacionadas