【问题标题】:Secure LDAP Authentication Issue安全 LDAP 身份验证问题
【发布时间】:2026-01-15 02:20:06
【问题描述】:

我在服务器 1 和服务器 2 上的 ASP.NET 4 (4.0.30319) 应用程序池中部署的网络表单的代码中使用以下 C# 代码。

PrincipalContext pc = new PrincipalContext(ContextType.Domain, "testnet.testad.org:636", "dc=testnet,dc=testad,dc=org");
bool validated = pc.ValidateCredentials(username, password, ContextOptions.Negotiate);

Server1 正在运行: windows server 2003 SP2
IIS 6.0
ASP.NET 版本 4.0.30319

验证需要 30-60 秒,具体取决于选项。
(注意:使用常规 ldap 会立即进行身份验证,没有延迟)

服务器 2 正在运行: Windows 服务器 2008 SP2
IIS 7.0
ASP.NET 版本 4.0.30319

运行与 Server1 完全相同的代码,Server2 几乎可以立即进行身份验证。
(我还尝试了针对另一台 IIS 7.0 服务器的代码,结果相同)

以前有人遇到过这个问题吗?
在 IIS 6.0 服务器与 IIS 7.0 服务器上是否有另一种身份验证方式?
有什么我需要配置、添加、删除等的吗?

感谢您对此的任何帮助。

.................................................. ..................................................... ................................................

[更新]

我在发出 ldaps 身份验证请求时打开了 wireshark。
我创建了一个包含超过 636 的所有请求的文件。
可以在这里查看:Server1 636 traffic

发现最大的差距是:

没有。 1949 年 1.115583 秒 - 编号 06788 14.501754 秒

14.64297 秒 6803 号 - 27.921379 秒 11742 号

该端口上的所有其他流量都在同一秒内发生。

注意:Server2 上的流量大致相同,但都发生在 2-3 秒之间。
可以在这里查看:Server2 636 traffic

我在登录时运行了 netstat -ano” 命令并发现了以下 ldaps 连接:

原始本地地址外部地址状态 PID
TCP 10.1.72.74:1761 10.1.72.54:636 已建立 3688
TCP 10.1.72.74:1800 10.1.72.54:636 已建立 3688
TCP 10.1.72.74:1825 10.1.72.54:636 已建立 3688

【问题讨论】:

  • 因此,使用端口 389 的身份验证调用会立即发生 - 连接超过 636 时从两台服务器颁发的证书,是否相同?唯一一次我注意到 速度急剧下降是在授权时引用绑定没有被正确抑制。您能否对 Server1 上的身份验证尝试进行 Wireshark 尝试以查看流量​​停止的位置?
  • @X3074861X 是的,使用端口 389 身份验证调用会立即发生。我不确定证书,但我的开发笔记本电脑上没有任何特殊证书,并且在调试时它的身份验证超过 636。我运行了 Wireshark 并在 Server1 上进行了身份验证尝试。我用结果和完整日志文件的位置更新了我上面的问题,所有流量都超过 636。
  • 我查看了那些 Wireshark 日志,您可能也注意到了,在 TLS 握手序列期间可以看到最大的流量障碍。在事件查看器中的 Server1 上,在系统日志下,您是否看到来自 Schannel 的任何警告或错误?除了 Negotiate 之外,您可能还需要定义 SSL 连接:bool validated = pc.ValidateCredentials(username, password, ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
  • 我查看了事件查看器系统日志,发现今天早上的 Schannel 错误:“尝试访问 SSL 客户端凭据私钥时发生致命错误。密码返回的错误代码模块是 0x80090016。”
  • 日期:2013 年 3 月 25 日时间:上午 10:11:06 来源:Schannel “尝试访问 SSL 客户端凭据私钥时发生致命错误。从加密模块返回的错误代码是 0x80090016。”无论我运行多少次缓慢的 ldaps 登录代码,我都无法复制此错误。

标签: c# authentication iis-7 ldap iis-6


【解决方案1】:

检查注册表项以查看支持的 SSL/TLS 版本;可能导致握手问题的问题...(请参阅下面给出的链接中的场景 5)

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols

对于一些相关场景及其解决方案,请阅读troubleshooting ssl related issues server certificate

【讨论】:

  • 我检查了您提到的注册表项,发现以下协议:PCT 1.0、SSL 2.0、SSL 3.0、TLS 1.0。我需要对这些做些什么吗?我在 https 流量超过 443 时没有问题。如上所述,我在 ldaps 流量超过 636 时遇到问题。但是,我按照提供的指南进行操作,发现: 1. 证书确实有相应的私钥。 2. 我安装并运行 SSL 诊断程序没有任何错误。 3. 我运行了 netstat -ano”,在上面的问题中添加了结果。 4. 我运行网络监视器并看到相同的时间间隔。除了时间差,一切看起来都不错?
  • hmm... 另一个 #note... 如果 LdapConnection 对象上的 ClientCertificates 属性和 LdapSessionOptions 对象上的 QueryClientCertificate 属性都已设置,则忽略 ClientCertificates 属性中指定的证书...即您的 ssl 证书看起来不错,ldap 服务器喷出什么?
  • 这看起来是解决/缩小问题范围的好地方...我会关注它..support.microsoft.com/kb/290483...特别是方法 3:使用 Microsoft Internet Explorer 和方法 4:使用Microsoft Platform SDK 中的 WebClient 示例,看起来有点过于简单,但可能会提供有用的信息。
【解决方案2】:

PrincipalContextValidateCredentials 方法基本上是 LDAP 绑定操作的包装器。为此要阅读的两篇关键文章是IADsOpenDSObject::OpenDSObjectLDAP ADsPath

您正在使用 SSL,因此如果您希望它尽可能高效,则需要指定它。 ValidateCredentials 方法的 ContextOptions 参数的文档实际上听起来不支持这个:

一个或多个 ContextOptions 枚举值的组合用于绑定到服务器的选项。此参数只能指定带或不带 SSL 的简单绑定,或协商绑定。

假设我误解了文档并且ValidateCredentials 方法确实支持指定Negotiate | SecureSocketLayer,你需要看看你是如何发送用户名的。在 OpenDSObject 文章中,它给出了关于用户名格式的建议:

您可以将 lpszUserName 作为以下字符串之一传入:

  1. 用户帐户的名称,例如“jeffsmith”。要单独使用用户名,您必须仅在 lnReserved 参数中设置 ADS_SECURE_AUTHENTICATION 标志。

  2. 来自以前版本的 Windows NT 的用户路径,例如“Fabrikam\jeffsmith”。

  3. 专有名称,例如“CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=Com”。要使用 DN,lnReserved 参数必须为零,或者必须包含 ADS_USE_SSL 标志

  4. 用户主体名称 (UPN),例如“jeffsmith@Fabrikam.com”。要使用 UPN,您必须为目标用户对象的 userPrincipalName 属性分配适当的 UPN 值。

您正在设置 SSL 标志,因此您必须使用 2、3 或 4。

附:在您的示例代码中,您在构造函数中指定域的 DNS 名称。如果您在真实代码中指定服务器,则需要添加 ServerBind 标志。

【讨论】:

  • 我正在使用的代码在其他三台服务器上运行,server2008、server2003 和 windows 7。我认为问题出在服务器本身而不是我使用的身份验证代码。
  • @Baxter 有时设置正确的标志会产生影响,例如this question
【解决方案3】:

看看我在ServerFault的回答...

服务可能无法访问:

C:\文档和设置\所有用户\应用程序 数据\Microsoft\Crypto\RSA\MachineKeys

您的提及:

日期:2013 年 3 月 25 日时间:上午 10:11:06 来源:Schannel “致命错误 尝试访问 SSL 客户端凭据私有时发生 键。

让它成为可能。

【讨论】:

  • 我运行进程监视器并按路径过滤结果包含“Crypto\RSA\MachineKeys”。当我运行登录页面时,我发现您指定的路径有很多拒绝访问条目。我在此处提供了日志条目:Process Monitor Logs“服务帐户”是指什么帐户可以访问它?
  • 另外,在日志中操作是“CreateFile”,但应用该操作的文件夹和机器密钥已经存在?文件夹的结果是“名称冲突”,机器密钥的结果是“拒绝访问”。
  • "NT AUTHORITY\NETWORK SERVICE" 被拒绝访问,所以给它读/执行权限
  • 我将“网络服务”的读取和执行/读取权限添加到在 procmon 中显示所有访问被拒绝错误的键。这立即解决了问题。超过 636 的 ldaps 登录现在可以立即工作,并且密钥显示 procmon 中的所有成功消息。非常感谢您的帮助。
最近更新 更多