我在这里看到一些奇怪的行为,使用PrincipalContext.ValidateCredentials
。该设置是父/子设置中的两个Active Directory域(因此我们有主域company.com
和子域development.company.com
)。ValidateCredentials对未知用户返回true?
当我根据主域验证凭据时,ValidateCredentials
的行为与预期的一样,对于良好的用户/传递对返回true,对其他任何情况返回false。
但是,如果我验证子域中的用户,则ValidateCredentials
对于良好的用户名/密码和无效用户均返回true。如果我向有效的用户提供了无效的密码,它会正确地返回false。
现在我现在正在通过首先执行UserPrincipal.FindByIdentity()
来解决此问题,如果用户存在,然后调用ValidateCredentials
- 但我想了解发生了什么。
另一个解决方法我看是通过传递用户名作为domain\username
为MSDN entry for ValidateCredentials
states:
在此功能中的每一个版本,用户名字符串可以在 一个多种不同格式。有关可接受的 格式类型的完整列表,请参阅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
)在命令提示符下运行它,并得到完全相同的结果。
我有两个域。我可以使用我的域的IP地址来调用验证凭据,并且如果我只是传递来自任一域的用户的用户名或密码,它就会成功。我有点惊讶,我不必提供这些额外的信息,并且有点困惑,然后我会如何确定我是否从正确的域名验证了正确的用户。 (不可能每个人都说一个jsmith?) – Greg