Как выполнить постраничный поиск на сервере Ldap с> 10000 записей, используя Novell.Directory.Ldap.NETStandard? - PullRequest
1 голос
/ 19 октября 2019

Это похоже на Как выполнить постраничный поиск на Ldap-сервере с большим количеством пользователей? , но предлагаемое решение не работает для нас.

Мы используем Novell.Directory. Ldap.NETStandard библиотека и нам нужно получить более 10000 записей из Active Directory. Мы используем LdapVirtualListControl для обработки подкачки, но этот элемент управления требует другого элемента управления: LdapSortControl. Active Directory имеет ограничение по умолчанию для сортировки (10000) и отправит ошибку 53 (нежелание выполнять), если результат превысит этот предел. Если опустить «Ошибка определения максимального результата», вместо этого мы получим LdapException: «Недоступное критическое расширение».

        // Connection
        var ldapConn = new LdapConnection()
        {
            SecureSocketLayer = true,
        };
        ldapConn.UserDefinedServerCertValidationDelegate += (sender, certificate, chain, sslPolicyErrors) => true;
        ldapConn.Connect(host, 636);            
        ldapConn.Bind(username, password);


        var searchConstraints = (LdapSearchConstraints)ldapConn.SearchConstraints.Clone();
        int contentCount = 0, count = 0, startIndex = 1, pageSize = 1000;
        bool exit;

        do
        {
            // Add Virtual List Control
            searchConstraints.setControls(new List<LdapControl>
            {
                { new LdapVirtualListControl(startIndex, 0, pageSize - 1, contentCount) },
                { new LdapSortControl(new LdapSortKey[1] { new LdapSortKey("name") },true) }
            }.ToArray());

            // Perform search
            var searchResult = ldapConn.Search(container, scope, query, null, false, searchConstraints);

            // Get entries in page
            var inPageCount = 0;
            while (searchResult.hasMore())
            {

                // Detect max result error
                LdapSortResponse ldapControl = searchResult.ResponseControls?.OfType<LdapSortResponse>().FirstOrDefault();
                if (ldapControl != null && ldapControl.ResultCode == 53) throw new LdapResultLimitExceeded(string.Format("ActiveDirectory: Ldap result limit exceeded in {0}.", container));

                searchResult.next();
                inPageCount++;
            }

            // Check for more pages 
            var control = FindResponseControl(searchResult, ActiveDirectoryService.LDAP_SERVER_VIRTUAL_LIST_VIEW_OID);
            if (control != null)
            {
                var response = new LdapVirtualListResponse(control.ID, control.Critical, control.getValue());
                startIndex += pageSize;
                contentCount = response.ContentCount;
                if (count + pageSize > contentCount) count = contentCount; else count += inPageCount;
            }
            exit = control == null;
        } while (count < contentCount && contentCount > 0 && !exit);

Как мы должны обрабатывать поиск для более чем 10000 записей?

...