Я вижу какое-то странное поведение, используя PrincipalContext.ValidateCredentials
. Настройка состоит из двух доменов Active Directory в родительской/дочерней настройке (поэтому у нас есть основной домен company.com
и поддомен development.company.com
).
Когда я проверяю учетные данные в отношении основного домена, ValidateCredentials
ведет себя так, как ожидалось, возвращает true для хороших пар user/pass и false для чего-либо еще.
Однако, если я проверяю пользователя в поддомене, ValidateCredentials
возвращает true как для хорошего имени пользователя/пароля, так и для недопустимых пользователей. Если я предоставляю действительного пользователя с недопустимым паролем, он правильно возвращает false.
Теперь я работаю над этим в настоящий момент, сначала выполняя UserPrincipal.FindByIdentity()
, и если пользователь существует, а затем вызывает ValidateCredentials
- но я хотел бы понять, что происходит.
Другим обходным решением, которое я рассмотрел, является передача имени пользователя через domain\username
в качестве записи MSDN для состояний ValidateCredentials
:
В каждой версии этой функции строка userName может находиться в одном из различные форматы. Полный список приемлемых типы форматов, см. документацию ADS_NAME_TYPE_ENUM.
... из которых указан этот вид имени пользователя. Но это приводит к тому, что ValidateCredentials
всегда возвращает true, независимо от того, какую комбинацию имени пользователя и пароля я передаю.
Соответствующий код:
bool authenticated = false;
// Various options tried for ContextOptions, [etc] inc. explicit username/password to bind to AD with -- no luck.
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain, null, ContextOptions.Negotiate, null, null))
{
log(pc.ConnectedServer + " => " + pc.UserName + " => " + pc.Name + " => " + pc.Container);
using (var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, username))
{
if (user != null)
{
log(user.DistinguishedName + "; " + user.DisplayName);
authenticated = pc.ValidateCredentials(username, password);
} else {
log("User not found");
// Debug only -- is FindByIdentity() needed. This should always return
// false, but doesn't.
authenticated = pc.ValidateCredentials(username, password);
}
}
}
return authenticated;
Любые предложения (разумные) приветствуются - я почесываю голову над этим, поскольку он просто противоречит ожиданиям.
Я должен добавить: это работает как я на моей машине, оба из которых являются членами основного домена. Однако я также попробовал запустить его в командной строке на моей машине в качестве пользователя поддомена (runas /user:subdomain\user cmd
) с точно такими же результатами.