DirectorySearcher FindOne() delay on initial execu

2019-02-17 07:08发布

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.

We noticed this on a client Windows 2008 server and then reproduced on our own Windows 2008 and Windows 7 boxes.

Here's what my simple .NET 4.0 C# app looks like. The delay occurs between the "Started" and "Finished" messages.

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");
            }
        }
    }
}

1条回答
We Are One
2楼-- · 2019-02-17 07:59

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).

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.

Finally, this MDSN page says that without any authentication flags, the username and password is sent cleartext. You should add the Secure flag.

查看更多
登录 后发表回答