【问题标题】:ValidateCredentials returns true for unknown user?ValidateCredentials 为未知用户返回 true?
【发布时间】:2011-09-07 15:09:04
【问题描述】:

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

当我针对主域验证凭据时,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 吗?)

标签: c# .net-4.0 active-directory


【解决方案1】:

稍后进行一些谷歌搜索(不是我整天进出谷歌试图找到这个),我已经found the answer

简单地说,如果在域中启用了来宾帐户,ValidateCredentials 将为未知用户返回 TRUE。我刚刚在 development.company.com 中检查了访客用户的状态,果然该帐户已启用。如果我禁用了来宾帐户,ValidateCredentials 会正确返回 false。

这是一个相当基本的问题,我不确定我是否热衷于这种行为……可惜 MSDN 上没有明确提及。

【讨论】:

  • 哇...这很容易错过,可能是一个很大的安全漏洞。感谢您的回答!
  • 5 年过去了,情况还是一样。看到principalContext.ValidateCredentials("blah", "blah", ContextOptions.Negotiate)true吓了一跳。
【解决方案2】:

我使用ContextOptions.SimpleBind 标志和ValidateCredentials 它解决了我的问题..

示例代码:

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

【讨论】:

    【解决方案3】:

    会不会和this有关:

    ValidateCredentials 方法绑定到在 构造函数。如果用户名和密码参数为空,则 验证构造函数中指定的凭据。 如果没有 凭证在构造函数中指定,用户名和 密码参数为空,此方法验证默认值 当前委托人的凭据

    【讨论】:

    • 否...事实证明,域级访客帐户已启用;如果我禁用它,ValidateCredentials 会做正确的事情。 (通常情况下,在一天中的大部分时间试图找到答案之后,在发布此消息后 20 分钟我找到了答案)。
    猜你喜欢
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 2015-09-11
    • 2023-04-07
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    相关资源
    最近更新 更多