PrincipalContext.ValidateCredentials always returns FALSE

白昼怎懂夜的黑 提交于 2019-12-03 10:30:33

I don't see where you initializes the "pwd" variable Maybe you should use ContextOption in this method to specify exactly the reqired behaviour. Sorry for too broad response but there is no much details in your question

Here's how ValidateCredentials(string, string) works: First, it tries to authenticate with the Negotiate, Signing, and Sealing context options. If this fails, it tries again with SimpleBind and SecureSocketLayer.

The problem is that the NT4 (AKA "legacy", AKA "down-level name") format (DOMAIN\UserName, or more correctly, NetBiosName\SamAccountName) doesn't work with Negotiate. But it does work with SimpleBind.

So what's probably happening when calling the 2-parameter ValidateCredentials() method, is that it first fails using Negotiate because it doesn't like the NT4 format, and then fails again when using simple bind.

During my own testing, I've found that the reason why it fails even after falling back to using simple bind is that it's not only using SimpleBind. It's using SimpleBind plus SecureSocketLayer. This means that it will still fail if the Active Directory server isn't set up correctly to use SSL (a common scenario for test environments).

As was mentioned in one of the comments, you NEVER, NEVER want to use SimpleBind by itself (without SecureSocketLayer), otherwise your passwords are sent over the network in plain text.

In the wild, I've seen that some Active Directory systems don't allow the use of simple binds at all, so you must make it work with Negotiate.

I've found 2 ways to deal with this problem:

1) If everything is happening on the same domain, you should be able to call ValidateCredentials with only the username (SAM account name), leaving out the "DOMAIN\" part. Then, it will work properly the first time with Negotiate.

2) If the domain part is important because there may be multiple domains involved (i.e. Domain1\UserA and Domain2\UserA are different people), then it gets a bit more complicated. In this case what I ended up doing was translating the NT4 name (DOMAIN\User) to "user principal name" format (e.g. LogonName@domain.com). There are a couple different ways to do this. The easiest is probably to use the 3-parameter overload of UserPrincipal.FindByIdentity(), and then grab the value of the UserPrincipalName property on the result. Another way would be to use a DirectorySearcher and query LDAP://domain for the userPrincipalName property of the user with the matching sAMAccountName value. Note: this solution will only work if all the domains involved are in the same forest.

It seems you are validating the user with domain\userName format. You might want to parse the domain name from userName and user the ValidateCredential.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!