Home > other >  How does UserPrincipal.FindByIdentity(PrincipalContext context, string identityValue) query Active D
How does UserPrincipal.FindByIdentity(PrincipalContext context, string identityValue) query Active D

Time:07-14

I am using .NET Framework 4.8 by necessity. I am running into an issue where: UserPrincipal.FindByIdentity(context, username); is resulting in a System.DirectoryServices.AccountManagement.MultipleMatchesException exception for a specific username. I can retrieve other users just fine. enter image description here

There are two accounts in my Active Directory that this user utilizes, however, both of them have different UPNs, sAMAccountNames, etc.

I took a look at the enter image description here

None of these lines of code result in a System.DirectoryServices.AccountManagement.MultipleMatchesException exception. The Sid and Guid look-ups fail because the username field isn't in the right format, and the other look-ups either pull the user or pull null.

So what am I missing here? Does the overload that leaves out a specific IdentityType do a different look-up than anything that's possible by supplying an IdentityType?

Edit #1: As Alex pointed out, I left out that I tried IdentityType.UserPrincipalName from my screenshot. This was just a cropping mistake. That call also does not throw an exception. enter image description here

CodePudding user response:

When you don't specify which identifier you're using, it's going to try them all at once. The source code is available now. The code that actually builds the query and executes it is here. Specifically it's line 617 where it starts building the filter. The source for IdentityClaimToFilter is here. Then it puts each condition in an OR.

So if we ignore Guid, Sid, and DistinguishedName, since we know those won't match, this is the relevant LDAP query (assuming the username you're using is "UserName"):

(|(sAMAccountName=UserName)(userPrincipalName=UserName)(name=UserName))

Try making that query in PowerShell and see if you get multiple matches (I'm assuming the computer you run this from is joined to the domain you want to search):

$search = [adsisearcher]"(|(sAMAccountName=UserName)(userPrincipalName=UserName)(name=UserName))"
$search.FindAll()

If the sAMAccountName of one account matches the name of another account, for example, you will get multiple matches.

CodePudding user response:

The docs say the identity value

can be any format that is contained in the IdentityType enumeration.

Probably what is happening is the string you are using is matching a type that is not unique. You should specify the IdentityType if possible or add logic for choosing the type.

Also your picture doesn't test IdentityType.UserPrincipalName

  • Related