为什么 DirectoryEntry.Invoke("SetPassword", value) 触发 Credential Required CryptoAPI Private Key

Why does DirectoryEntry.Invoke("SetPassword", value) trigger Credential Required CryptoAPI Private Key

我最近一直在处理一些旧代码,在测试时,我开始看到 "Credential Required" window:"Do you want to allow the app to access your private key? Key description: CryptoAPI Private Key."

它发生在这行代码:

object result = this.m_DirectoryEntry.Invoke(MethodName, Argument);

其中 MethodNameSetPassword

单击“不允许”仍允许该方法继续。

当我 运行 在 Visual Studio 之外的应用程序时也会发生这种情况。这将不是可接受的用户体验。

为什么会这样? 我该如何阻止它?

我在 Server 2016 计算机上使用 Visual Studio Community 2015 Update 3。项目使用.NET 4.5.2.

重新创建的代码

新的解决方案。 在项目属性中,将目标框架设置为 .NET Framework 4.5.2。 添加对 System.DirectoryServices.

的引用
namespace SetPasswordCryptoApiTester1
{
    using System;
    using System.DirectoryServices;

    class Program
    {
        static void Main(string[] args)
        {
            var adsPath = "LDAP://CN=path_to_user";

            using (var de = new DirectoryEntry(adsPath))
            {
                Console.WriteLine("Press a key to set the password...");
                Console.ReadKey(true);

                object result = de.Invoke("SetPassword", "Sausag32");

                Console.WriteLine("Press a key to continue...");
                Console.ReadKey(true);
            }
        }
    }
}

也许您已经解决了这个问题,但我想我还是会回答。虽然我不能确定发生了什么。

调用本机 Windows IADsUser 对象的 SetPassword 方法。在 Remarks section of the documenation 中,它描述了尝试重置密码的 3 种方法。可能是这些方法中的一种导致了 pop-up,当您单击 "Don't allow" 时,它只是移动到下一个。

它使用的第一个是 LDAP over SSL (LDAPS)。我从未见过这种情况,但在您的域上设置 LDAPS 的方式可能有些奇怪,它可能会要求提供客户端证书?

您可以测试这个理论...在 PowerShell 中,试试这个:

Invoke-WebRequest https://example.com:636

(将 "example.com" 替换为您的域名)您将收到证书错误(可能会弹出同样的消息?),但如果 SSL 握手有效,那么您应该会收到 "The underlying connection was closed"。

如果您在尝试通过 PowerShell 时确实遇到了弹出窗口,那么我认为除非您是域管理员,否则您无能为力。必须在域控制器上进行一些更改。