UserPrincipal.FindByIdentity 权限

发布于 2024-09-16 08:00:59 字数 652 浏览 7 评论 0原文

我正在尝试使用 .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)

想法?

I'm attempting to use the .NET System.DirectoryServices.AccountManagement library to obtain the UserPrincipal for a particular Active Directory user.

I've got the following code:

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

This code is running as a valid domain user, but when I execute it I get the following exception:

System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

What's interesting is that I can make the following call, using the same context, without a problem:

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

Ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

贪恋 2024-09-23 08:00:59

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

验证起作用的原因是它使用提供的凭据绑定到目录。

You need to use the the PrincipalContext constructor that takes username and password.

The reason that Validate works is because its using the provided credentials to bind to the directory.

⒈起吃苦の倖褔 2024-09-23 08:00:59

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

假设您的域名为 yourdomain.com,您可以告诉 Windows 在与任何包含 yourdomain.com 的计算机进行通信时始终使用特定的用户名和密码。

=== Windows 7/2008 ===

  1. 启动“Crendentail Manager”。
  2. 在 Windows 凭据部分下,单击添加 Windows 凭据
  3. 在网络地址中,输入 *.yourdomain.com
  4. 在用户名和密码中,输入错误的用户名或错误密码

== = Windows XP/2000/2003 ===

  1. 单击开始并运行
  2. 输入 control keymgr.dll
  3. 单击“存储的用户名和密码”对话框上的添加按钮
  4. 在服务器文本框中,输入 * .yourdomain.com
  5. 在用户名和密码中,输入错误的用户名或错误的密码

如果这确实是您面临的问题,简单的解决方法是删除存储的密码。

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

为什么 UserPrincipal.FindByIdentity 不起作用?
如果您没有任何存储的密码,通常它应该可以工作,因为 Windows 将仅使用当前登录用户 TGT 票证来交换 LDAP 服务器服务票证。不涉及用户名/密码验证过程。但是,如果您的用户名密码确实错误,Windows 会认为不应使用当前登录用户 TGT 票证。相反,它应该使用存储的网络密码获取新的 TGT 票证。这就是您看到 System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): 登录失败: 未知的用户名或错误密码的原因。

It sounds like you have a stored network credentials. In Windows, you can specify to use a different network credentials when trying to reach a network resources. I can reproduce exactly the same problem as you are seeing by setting up a wrong network credentials.

Assuming your domain is called yourdomain.com, you can tell Windows to always use a specific username and password whenever it talks to any computers with suffice yourdomain.com.

=== Windows 7/2008 ===

  1. Launch the "Crendentail Manager".
  2. Under Windows credentials section, click Add a Windows credentials
  3. In network address, put in *.yourdomain.com
  4. In username and password, put in a wrong username or wrong password

=== Windows XP/2000/2003 ===

  1. Click Start and Run
  2. Type in control keymgr.dll
  3. Click Add button on "Stored User Names and Passwords" dialog
  4. In server text box, put in *.yourdomain.com
  5. In username and password, put in wrong username or wrong password

If this is really the problem that you are facing, the easy fix is to remove the stored passwords.

Why does context.ValidateCredentials(username, password, ContextOptions.Negotiate) work? It's simply because you are initializing another Kerberos/NTLM authentication since you provides uername and password again. Under the hood, if Kerberos is chosen, it would send the domain controller the provided username and password and exchange for a Kerberos TGT ticket. Then, your machine get a service ticket on the LDAP server using this TGT ticket. Then, your machine will send this service ticket to the LDAP server. Note that this service ticket won't be retained in the current logon session.

Why UserPrincipal.FindByIdentity doesn't work?
If you don't have any stored password, normally it should work because Windows will just use the current logon user TGT ticket to exchange for the LDAP server service ticket. There is no username/password validation process involved. However, if you do have a bad username password, Windows would think it shouldn't use the current logon user TGT ticket. Instead, it should get a new TGT ticket using the stored network password. That's the reason you are seeing System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文