UserPrincipal.FindByIdentity权限

时间:2010-08-26 21:16:11

标签: c# .net active-directory ldap directoryservices

我正在尝试使用.NET System.DirectoryServices.AccountManagement库来获取特定Active Directory用户的UserPrincipal。

我有以下代码:

PrincipalContext context = new PrincipalContext(ContextType.Domain, "DomainName");
userPrincipal = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username);

此代码作为有效的域用户运行,但是当我执行它时,我得到以下异常:

  

System.DirectoryServices.DirectoryServicesCOMException(0x8007052E):登录失败:未知用户名或密码错误。

有趣的是,我可以使用相同的上下文进行以下调用,而不会出现问题:

context.ValidateCredentials(username, password, ContextOptions.Negotiate)

想法?

2 个答案:

答案 0 :(得分:12)

您需要使用带有用户名和密码的PrincipalContext构造函数。

Validate工作的原因是因为它使用提供的凭据绑定到目录。

答案 1 :(得分:3)

听起来您拥有存储的网络凭据。在Windows中,您可以指定在尝试访问网络资源时使用其他网络凭据。通过设置错误的网络凭据,我可以重现与您所看到的完全相同的问题。

假设您的域名为yourdomain.com,您可以告诉Windows在与任何具有足够的yourdomain.com的计算机通话时始终使用特定的用户名和密码。

=== Windows 7/2008 ===

  1. 启动“Crendentail Manager”。
  2. 在“Windows凭据”部分下,单击“{1}}
  3. 在网络地址中,输入Add a Windows credentials
  4. 在用户名和密码中输入错误的用户名或密码错误
  5. === Windows XP / 2000/2003 ===

    1. 点击开始并运行
    2. 输入*.yourdomain.com
    3. 单击“存储的用户名和密码”对话框中的“添加”按钮
    4. 在服务器文本框中,输入control keymgr.dll
    5. 在用户名和密码中输入错误的用户名或密码错误
    6. 如果这确实是您面临的问题,那么简单的解决方法就是删除存储的密码。

      为什么context.ValidateCredentials(用户名,密码,ContextOptions.Negotiate)有效?这只是因为您正在初始化另一个Kerberos / NTLM身份验证,因为您再次提供*.yourdomain.comuername。在引擎盖下,如果选择了Kerberos,它将向域控制器发送提供的用户名和密码,并交换Kerberos TGT票证。然后,您的计算机使用此TGT票证在LDAP服务器上获取服务票证。然后,您的计算机将此服务票证发送到LDAP服务器。请注意,此服务票证不会保留在当前登录会话中。

      为什么password不起作用? 如果您没有任何存储密码,通常它应该可以工作,因为Windows将只使用当前登录用户TGT票证来交换LDAP服务器服务票证。没有涉及用户名/密码验证过程。但是,如果您的用户名密码错误,Windows会认为它不应使用当前的登录用户TGT票证。相反,它应该使用存储的网络密码获得新的TGT票证。这就是你看到UserPrincipal.FindByIdentity

      的原因