0

When a user is Windows authenticated in my WebAPI app, and I use UserPrincipal.Current, I get the error that

System.DirectoryServices.AccountManagement.GroupPrincipal cannot be converted to System.DirectoryServices.AccountManagement.UserPrincipal

at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)
at System.DirectoryServices.AccountManagement.UserPrincipal.get_Current()

I am not the only one to have this problem.

But I have the ApiController.User object filled correctly. So I tried:

Principal principal = (Principal)User;
principal.GetUnderlyingObject(...

But it won't do, because

IPrincipal cannot be converted to Principal

So, I have to convert to a Windows principal, which works:

WindowsPrincipal winPrincipal = (WindowsPrincipal)User;

And then I have to ask AD for that specific user:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
{
    Principal principal = Principal.FindByIdentity(pc, windowsPrincipal.Identity.Name);
    principal.GetUnderlyingObject(...
}

In 9 of 10 cases this works, but for some users, principal is null, although the user is authenticated. The affected users are all part of a certain subdomain. What am I overlooking? Is there another, more reliable, method to always get the AD principal of the Windows authenticated principal?

Community
  • 1
  • 1
Alexander
  • 19,906
  • 19
  • 75
  • 162

1 Answers1

1

You need to keep the IPrincipal (and IIdentity) interfaces which are core .NET security interfaces separated from the UserPrincipal in AD - those are NOT the same thing and not related directly.

In AD, you can always use

UserPrincipal current = UserPrincipal.Current;

to get the current user's AD information

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Using UserPrincipal.Current throws the error that "System.DirectoryServices.AccountManagement.GroupPrincipal" cannot be converted to "System.DirectoryServices.AccountManagement.UserPrincipal" (`at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue), at System.DirectoryServices.AccountManagement.UserPrincipal.get_Current()`). I just added that to the original post. – Alexander Feb 18 '15 at 17:28
  • @Alexander: in that case, your web app might be running under an app pool that uses a Windows **group** - in that case, you need to cast it to `GroupPrincipal` instead – marc_s Feb 18 '15 at 17:48
  • I don't need the app pool, I need the user that has logged in. And the "cast" that fails is done inside `UserPrincipal.get_Current()`, which is a Microsoft builtin - so I can't change that cast, I can only abstain from using `UserPrincipal.Current`. – Alexander Feb 18 '15 at 17:55