我在这里使用 PrincipalContext.ValidateCredentials
看到一些奇怪的行为。该设置是父/子设置中的两个 Active Directory 域(因此我们有主域 company.com
和子域 development.company.com
)。
当我针对主域验证凭据时,ValidateCredentials
的行为符合预期,对于良好的用户/密码对返回 true,对于其他任何内容返回 false。
但是,如果我验证子域中的用户,对于良好的用户名/密码和无效用户,ValidateCredentials
都会返回 true。如果我向有效用户提供无效密码,它会正确返回 false。
现在我正在解决这个问题,首先执行 UserPrincipal.FindByIdentity()
,如果用户存在,然后调用 ValidateCredentials
——但我想了解这是怎么回事。
我研究过的另一个解决方法是将用户名作为 domain\username 传递.accountmanagement.principalcontext.validatecredentials.aspx">ValidateCredentials
的 MSDN 条目说明:
在此函数的每个版本中,用户名字符串可以位于以下之一
各种不同的格式。有关可接受的完整列表
格式类型,请参阅 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
) 的身份在我的计算机上的命令提示符中运行它,结果完全相同。
I'm seeing some odd behaviour here using PrincipalContext.ValidateCredentials
. The set-up is two Active Directory domains in parent/child setup (so we have primary domain company.com
and sub-domain development.company.com
).
When I validate credentials against the primary domain, ValidateCredentials
behaves as expected, returning true for good user/pass pairs, and false for anything else.
However if I validate a user in the sub-domain, ValidateCredentials
returns true for both good username/passwords AND invalid users. If I provide a valid user with an invalid password, it correctly returns false.
Now I'm working around it at the moment by doing UserPrincipal.FindByIdentity()
first and if the user exists, then calling ValidateCredentials
-- but I'd like to understand what's going on.
Another workaround I've looked at is by passing the username through as domain\username
as the MSDN entry for ValidateCredentials
states:
In each version of this function, the userName string can be in one of
a variety of different formats. For a complete list of the acceptable
types of formats, see the ADS_NAME_TYPE_ENUM documentation.
...of which this form of username is listed. But this causes ValidateCredentials
to always return true, no matter what combination of username and password I pass in.
The pertinent code is:
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;
Any and all (sensible) suggestions welcome -- I'm scratching my head over this as it just goes against all expectations.
I ought to add: this is running as myself on my machine, both of which are members of the primary domain. However I've also tried running it in a command prompt on my machine as a user of the sub-domain (runas /user:subdomain\user cmd
) with exactly the same results.
发布评论
评论(3)
后来进行了一些谷歌搜索(并不是说我一整天都在谷歌中进出试图找到这个),我找到了答案。
简而言之,如果在域中启用了来宾帐户,ValidateCredentials 将为未知用户返回 TRUE。我刚刚在development.company.com 中检查了来宾用户的状态,果然该帐户已启用。如果我禁用了来宾帐户,ValidateCredentials 会正确返回 false。
这是一个相当基本的陷阱,不确定我是否热衷于这种行为......遗憾的是 MSDN 上没有明确提及。
Some amount of googling later (not that I've been in and out of google all day trying to find this anyway), I've found the answer.
Put simply, if the Guest account is enabled in the domain, ValidateCredentials will return TRUE for an unknown user. I've just checked the status of the guest user in development.company.com, and sure enough the account is enabled. If I have the guest account disabled, ValidateCredentials correctly returns false.
This is a fairly fundamental gotcha, not sure I'm keen on this behaviour... pity it's not explicitly mentioned on MSDN.
我已将 ContextOptions.SimpleBind 标志与 ValidateCredentials 一起使用,它解决了我的问题。
示例代码:
I have used
ContextOptions.SimpleBind
flag withValidateCredentials
it solved my problem..Sample code:
它是否与此有关:
Could it be related to this: