2011-09-07 37 views
9

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

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

但是,如果我验证子域中的用户,则ValidateCredentials对于良好的用户名/密码和无效用户均返回true。如果我向有效的用户提供了无效的密码,它会正确地返回false。

现在我现在正在通过首先执行UserPrincipal.FindByIdentity()来解决此问题,如果用户存在,然后调用ValidateCredentials - 但我想了解发生了什么。

另一个解决方法我看是通过传递用户名作为domain\usernameMSDN 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)在命令提示符下运行它,并得到完全相同的结果。

+0

我有两个域。我可以使用我的域的IP地址来调用验证凭据,并且如果我只是传递来自任一域的用户的用户名或密码,它就会成功。我有点惊讶,我不必提供这些额外的信息,并且有点困惑,然后我会如何确定我是否从正确的域名验证了正确的用户。 (不可能每个人都说一个jsmith?) – Greg

回答

16

一定量的谷歌搜索后(不是我一直在进出谷歌整天试图找到这个无论如何),我found the answer。简而言之,如果在域中启用了Guest帐户,则ValidateCredentials将针对未知用户返回TRUE。我刚刚在development.company.com上检查了访客用户的状态,并确信已启用该帐户。如果我禁用访客帐户,则ValidateCredentials将正确返回false。

这是一个相当基本的疑难杂症,不知道我对这种行为很感兴趣......可惜它没有在MSDN上明确提及。

+0

哇......这是一个容易错过,可能是一个很大的安全漏洞。感谢你的回答! –

+2

为什么AD API必须如此死脑筋? –

+0

5年过去了,案件依然如此。惊讶地发现'principalContext.ValidateCredentials(“blah”,“blah”,ContextOptions.Negotiate)'返回'true'。 – trailmax

0

莫非涉及到this

的ValidateCredentials方法结合到所述 构造指定的服务器。如果用户名和密码参数为空,则验证构造函数中指定的凭证。 如果在构造函数中未指定 凭据,并且用户名和 密码参数为空,则此方法将验证当前主体的默认 凭据。

+0

不,因为它结果,域级别的访客帐户已启用;如果我禁用它,ValidateCrendentials会做正确的事情。 (通常情况下,在一天中的大部分时间试图找到答案,发布后20分钟我找到答案)。 –

+0

是的总是这样:) – TheCodeKing

相关问题