I'm attempting to use the .NET System.DirectoryServices.AccountManagement
library to obtain the UserPrincipal for a particular Active Directory user.
I've got the following code:
PrincipalContext context = new PrincipalContext(ContextType.Domain, "DomainName");
userPrincipal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);
This code is running as a valid domain user, but when I execute it I get the following exception:
System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.
What's interesting is that I can make the following call, using the same context, without a problem:
context.ValidateCredentials(username, password, ContextOptions.Negotiate)
Ideas?
You need to use the the PrincipalContext
constructor that takes username and password.
The reason that Validate works is because its using the provided credentials to bind to the directory.
It sounds like you have a stored network credentials. In Windows, you can specify to use a different network credentials when trying to reach a network resources. I can reproduce exactly the same problem as you are seeing by setting up a wrong network credentials.
Assuming your domain is called yourdomain.com
, you can tell Windows to always use a specific username and password whenever it talks to any computers with suffice yourdomain.com.
=== Windows 7/2008 ===
Add a Windows credentials
*.yourdomain.com
=== Windows XP/2000/2003 ===
control keymgr.dll
*.yourdomain.com
If this is really the problem that you are facing, the easy fix is to remove the stored passwords.
Why does context.ValidateCredentials(username, password, ContextOptions.Negotiate) work? It's simply because you are initializing another Kerberos/NTLM authentication since you provides uername
and password
again. Under the hood, if Kerberos is chosen, it would send the domain controller the provided username and password and exchange for a Kerberos TGT ticket. Then, your machine get a service ticket on the LDAP server using this TGT ticket. Then, your machine will send this service ticket to the LDAP server. Note that this service ticket won't be retained in the current logon session.
Why UserPrincipal.FindByIdentity
doesn't work?
If you don't have any stored password, normally it should work because Windows will just use the current logon user TGT ticket to exchange for the LDAP server service ticket. There is no username/password validation process involved. However, if you do have a bad username password, Windows would think it shouldn't use the current logon user TGT ticket. Instead, it should get a new TGT ticket using the stored network password. That's the reason you are seeing System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With