PrincipalContext::ValidateCredentials 抛出带有无效密码的 LdapException

Posted

技术标签:

【中文标题】PrincipalContext::ValidateCredentials 抛出带有无效密码的 LdapException【英文标题】:PrincipalContext::ValidateCredentials throws LdapException with invalid password 【发布时间】:2017-09-21 01:27:26 【问题描述】:

我有一个 Windows 应用程序,它正在尝试使用以下代码验证 Active Directory 上的用户/密码。

PrincipalContext^ pc = gcnew PrincipalContext(ContextType::Domain);
// validate the credentials
bool isValid = pc->ValidateCredentials(userName, password);
if(!isValid)

    throw gcnew SecurityTokenValidationException("Invalid user ID / password");


UserPrincipal^ upUser = UserPrincipal::FindByIdentity(pc, userName);
if(upUser && !upUser->IsMemberOf(pc, IdentityType::SamAccountName, ADGroup))

    String^ msg = "User " + userName + " is not a member of the " + ADGroup + " group.";
    throw gcnew SecurityTokenValidationException(msg);

在 Visual Studio 2008 / .NET 3.5 / 32 位版本下运行此代码时,如果我给了一个有效用户但密码无效,ValidateCredentials() 将返回 false。

使用 Visual Studio 2013 / .NET 4.0 / 64 位版本,完全相同的代码会引发 LdapException:

System.DirectoryServices.Protocols.LdapException: The LDAP server is unavailable.
at System.DirectoryServices.Protocols.LdapConnection.Connect()
at System.DirectoryServices.Protocols.LdapConnection.BindHelper(NetworkCredential newCredential, Boolean needSetCredential)
at System.DirectoryServices.AccountManagement.CredentialValidator.lockedLdapBind(LdapConnection current, NetworkCredential creds, ContextOptions contextOptions)
at System.DirectoryServices.AccountManagement.CredentialValidator.BindLdap(NetworkCredential creds, ContextOptions contextOptions)
at System.DirectoryServices.AccountManagement.CredentialValidator.Validate(String userName, String password)
at System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials(String userName, String password)
at soapcon.ADUserNameValidator.Validate(String userName, String password)

如果我断开我的 PC 与网络的连接,我会收到 PrincipalServerDownException 异常,所以我很确定我实际上是在与我们的 AD 服务器通话。

这是我的代码有问题,还是 .NET 有问题,或者可能是由于我们的 Active Directory 服务设置太旧(Windows 2000)?

【问题讨论】:

那不是c#,而是c++ .net。顺便说一句,应用程序池是否在 IIS 配置中的域帐户下执行? IIS 的行为与 Cassiny 不同 @bradbury9 我没有运行 IIS,它只是一个 Windows 应用程序,在我的开发者域帐户下运行。 我想知道不同的框架是否会使用不同的默认身份验证选项,您可以在这两种情况下尝试.ValidateCredentials (String, String, ContextOptions) 重载吗? @bradbury9 您想将此评论添加为答案吗?使用 'ContextOptions::Negotiate | 的 ContextOptions上下文选项::签名 | ContextOptions::Sealing;'似乎解决了我的问题。 完成,很高兴为您提供帮助 :-) 【参考方案1】:

我想知道不同的框架是否会使用不同的默认身份验证选项,您可以在这两种情况下尝试.ValidateCredentials (String, String, ContextOptions) 重载吗?

根据评论,在重载中试试这个ContextOptions 标志:

ContextOptions::Negotiate | ContextOptions::Signing | ContextOptions::Sealing

【讨论】:

以上是关于PrincipalContext::ValidateCredentials 抛出带有无效密码的 LdapException的主要内容,如果未能解决你的问题,请参考以下文章