views:

116

answers:

1

I am having an issue using the GetAuthorizationGroups method of the UserPrincipal class in a web application.

Using the following code, I am receiving "While trying to retrieve the authorization groups, an error (5) occurred"

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

I believe this code works to an extent.

  • When I view the context object, I can see the server and username/password have been resolved correctly in the object
  • When I view the p object, I can see AD details have been populated like phone no etc.

Here is the stack trace from the 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

By removing the username and password details from the PrincipalContext constructor and changing the applicationpool (in iis7) to run as the same user ([email protected]) - the following code works.

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

I need to get the code in the first example to work - I do not want run the application pool as a domain user just to get this code working.

A: 

Error 5 indicates ERROR_ACCESS_DENIED, which suggests a permissions related issue. That said, the following code has just worked for me, running on Windows 7 with the website running as the default application pool:

Content of "body" of .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();
}

In my example logon_domain was the lefthand of domain_name\username, rather than the style of domain specification you'd used. My solution may or may not work for you. If it doesn't, it does point to a permissions issue somewhere.

Rob
Thanks Rob, I have tried many combinations in the PrincipalContext constructor with not luck. I think the root cause of my problem is knowing the permission requirements of the application user to invoke the GetAuthorizationGroups() method. My application user has read all information rights to objects in the OU. Currently I am doing this the long way by reading the memberOf property of users. This howerver is only the first level and not recursive.
Adam Jenkin
FWIW, I had a version working where I used `var Context = new PrincipalContext(ContextType.Domain, "logon_domain");`, so the context was purely a domain one and that also worked without error in Win7/default application pool. Is the machine you're running your code on domain joined?
Rob
Yes, joined to a domain. if I use the PrincipalContext(ContextType.Domain, "logon_domain") constructor with network service (AppPool) it doesn't work. If I change the AppPool to run as the same user as used in method PrincipalContext(ContextType.Domain, null, "DC=MyCompany,DC=COM", "username", "password") it does work!
Adam Jenkin