C# ValidateCredentials是否为未知用户返回true?

C# ValidateCredentials是否为未知用户返回true?,c#,.net-4.0,active-directory,C#,.net 4.0,Active Directory,我在这里看到一些奇怪的行为,使用PrincipalContext.ValidateCredentials。设置是父/子设置中的两个Active Directory域(因此我们有主域company.com和子域development.company.com) 当我针对主域验证凭据时,ValidateCredentials的行为与预期一样,对于良好的用户/过程对,返回true;对于其他任何情况,返回false 但是,如果我验证子域中的用户,ValidateCredentials会为正确用户名/密码和

我在这里看到一些奇怪的行为,使用
PrincipalContext.ValidateCredentials
。设置是父/子设置中的两个Active Directory域(因此我们有主域
company.com
和子域
development.company.com

当我针对主域验证凭据时,
ValidateCredentials
的行为与预期一样,对于良好的用户/过程对,返回true;对于其他任何情况,返回false

但是,如果我验证子域中的用户,
ValidateCredentials
会为正确用户名/密码和无效用户返回true。如果我为有效用户提供了无效密码,它将正确返回false

现在我正在解决这个问题,首先执行
UserPrincipal.FindByIdentity()
,如果用户存在,然后调用
ValidateCredentials
——但我想了解发生了什么

我研究的另一个解决方法是将用户名作为
domain\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
),结果完全相同。

它可能与:

ValidateCredentials方法绑定到中指定的服务器 构造器。如果用户名和密码参数为空,则 将验证构造函数中指定的凭据如果否 在构造函数中指定了凭据,以及用户名和 密码参数为null,此方法验证默认值 当前主体的凭据


后来我在谷歌上搜索了一段时间(并不是说我一整天都在谷歌内外寻找这个),我已经找到了

简单地说,如果在域中启用来宾帐户,则对于未知用户,ValidateCredentials将返回TRUE。我刚刚在development.company.com中检查了来宾用户的状态,并且确信该帐户已启用。如果禁用来宾帐户,ValidateCredentials将正确返回false


这是一个相当基本的问题,我不确定我是否喜欢这种行为。。。遗憾的是,MSDN中没有明确提到它。

我使用了
上下文选项。SimpleBind
标记为
ValidateCredentials
解决了我的问题

示例代码:

    using (var context = new PrincipalContext(ContextType.Domain, "DOMAIN", null))
    {
        bool loginResult = context.ValidateCredentials(username, password, ContextOptions.SimpleBind); // returns false for unknown user
    }

不事实证明,域级来宾帐户已启用;如果我禁用它,ValidateRendentials会做正确的事情。(和往常一样,在一天的大部分时间试图找到答案后,在发布本文20分钟后,我找到了答案)。哇。。。这是一个很容易的失误,可能是一个很大的安全漏洞。谢谢你的回答!5年过去了,情况依然如此。看到
principalContext.ValidateCredentials(“blah”,“blah”,ContextOptions.congregate)”时,我非常吃惊。
返回
true
。我有两个域。我可以使用我的域的ip地址来调用验证凭据,如果我只传递来自任一域的用户的用户名或密码,验证就会成功。我有点惊讶,我不必提供这些额外的信息,然后我有点困惑如何确定我正在验证来自正确域的正确用户。(难道不可能每个人都说一个jsmith吗?)