问题描述
我看到在执行 DirectorySearcher FindOne() 和我看到的第一个网络数据包发送到 LDAP 服务器之间存在 2-5 秒的初始延迟.初始执行后,后续执行会立即完成约 45 秒.在那段快速执行之后,下一次执行将被延迟,并且所有后续执行都将立即完成.似乎正在进行某种缓存,但我无法找到任何资源来确认或描述导致初始延迟的原因.
I'm seeing an initial delay of 2-5 seconds between the time that I execute DirectorySearcher FindOne() and the first network packet I see go out to the LDAP server. After the initial execution, subsequent executions complete instantly for about 45 seconds. After that period of fast executions, the next execution will be delayed and again all subsequent executions will complete instantly. It seems like there's some sort of caching going on but I haven't been able to find any resources confirming that or describing what is causing the initial delay.
我们在客户端 Windows 2008 服务器上注意到了这一点,然后在我们自己的 Windows 2008 和 Windows 7 机器上重现.
We noticed this on a client Windows 2008 server and then reproduced on our own Windows 2008 and Windows 7 boxes.
这是我的简单 .NET 4.0 C# 应用程序的外观.延迟发生在Started"和Finished"消息之间.
Here's what my simple .NET 4.0 C# app looks like. The delay occurs between the "Started" and "Finished" messages.
知道为什么在初始 FindOne() 执行时会出现这种延迟吗?非常感谢任何帮助!
Any idea why this delay occurs on the initial FindOne() execution? Any help is much appreciated!
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
namespace LdapTest
{
class Program
{
static void Main(string[] args)
{
string[] fetchAttributes;
fetchAttributes = new string[] { "{string[0]}" };
using (DirectoryEntry searchRoot = new DirectoryEntry("LDAP://localserver/ou=lab,dc=ourdomain,dc=com", "cn=binduser,ou=Services,dc=ourdomain,dc=com", "Password", AuthenticationTypes.ReadonlyServer))
{
using (DirectorySearcher searcher = new DirectorySearcher(searchRoot, "(sAMAccountName=UserName)", fetchAttributes, SearchScope.Subtree))
{
Console.WriteLine("Started");
SearchResult result = searcher.FindOne();
Console.WriteLine("Finished");
}
}
}
}
推荐答案
根据LDAP ADsPath MSDN 文章,如果您的绑定 LDAP 路径指向服务器,则应指定 ServerBind
标志以避免不必要的网络流量.它还建议提供服务器的完整 DNS 名称.此外,ReadonlyServer
标志在指向服务器时是没有意义的.所以我的第一个建议是用 ServerBind
替换 ReadonlyServer
标志(最好给出完整的 DNS 名称),或删除字符串的服务器部分(在您的示例中,使它是 LDAP://ou=lab,dc=ourdomain,dc=com 或 LDAP://ourdomain.com/ou=lab,dc=ourdomain,dc=com).
According to the LDAP ADsPath MSDN article, you should specify the ServerBind
flag if your binding LDAP path points to a server to avoid unnecessary network traffic. It also recommends giving the full DNS name of the server. In addition, the ReadonlyServer
flag is meaningless when pointing to a server. So my first suggestion is to replace the ReadonlyServer
flag with ServerBind
(and preferably give the full DNS name), or remove the server part of the string (in your example, make it LDAP://ou=lab,dc=ourdomain,dc=com or LDAP://ourdomain.com/ou=lab,dc=ourdomain,dc=com).
要查看的另一件事是您通过专有名称提供用户名.如果您查看 DirectoryEntry 使用的核心 API,IADsOpenDSObject::OpenDSObject,它要求 lpReserved 标志 [DirectoryEntry 中的 AuthenticationTypes
参数] 为零 [None
] 或包含 ADS_USE_SSL [SecureSocketsLayer
] 标志在传递用户名的专有名称时.请注意,SecureSocketsLayer
标志要求 Active Directory 需要安装证书服务器才能使用此标志.您可能希望以不同的格式传递用户名.
The other thing to look at is that you're providing the username by distinguished name. If you look at the core API that DirectoryEntry uses, IADsOpenDSObject::OpenDSObject, it requires that the lpReserved flag [the AuthenticationTypes
parameter in DirectoryEntry] is zero [None
] or includes the ADS_USE_SSL [SecureSocketsLayer
] flag when passing a distinguished name for the username. Note that the SecureSocketsLayer
flag requires that Active Directory requires that a certificate server is installed before you can use this flag. You might want to pass the username in a different format.
最后,这个 MDSNpage 表示没有任何身份验证标志,用户名和密码以明文形式发送.您应该添加 Secure
标志.
Finally, this MDSN page says that without any authentication flags, the username and password is sent cleartext. You should add the Secure
flag.
这篇关于DirectorySearcher FindOne() 初始执行延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!