Поиск в Active Directory в Angular 7 - PullRequest
       7

Поиск в Active Directory в Angular 7

0 голосов
/ 11 декабря 2018

Я использую поле поиска ввода в угловой реактивной форме при поиске пользователей AD.Поэтому, когда вы начнете вводить свое имя, вы должны получить некоторые опции автозаполнения для поля.Для этого я вызываю метод веб-API из моего углового приложения, которое, в свою очередь, возвращает мне список пользователей.Я связываю этот список пользователей со списком данных поля ввода.Я использую следующий код в своем веб-интерфейсе: -

 public List<string> ADUsers()
 {
    List<string> users = new List<string>();  
    using (var context = new PrincipalContext(ContextType.Domain, "abc.in"))
    {
      using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
      {
         foreach (var result in searcher.FindAll())
         {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            if(de.Properties["givenName"].Value != null && de.Properties["sn"].Value != null)
              users.Add(de.Properties["givenName"].Value + " " + de.Properties["sn"].Value);
         }
       }
     }
     return users;
 }

Поскольку число пользователей слишком велико, требуется время, чтобы вернуть список в угловой (20-25 секунд), что в свою очередь занимает времяотразить в поле ввода реактивной формы.Я новичок в угловых и в основном разработчик .net.Не могли бы вы предложить какой-нибудь способ выяснить какое-нибудь адаптивное решение?или может быть возможно иметь функциональность в angular, чтобы я не вызывал метод web api для этого?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Я также сделал применение фильтров в моем подходе, и это очень быстро.Код приведен ниже: -

public List<string> ADUsers(string filter)
{
    List<string> users = new List<string>();

    PrincipalContext domainContext = new PrincipalContext(ContextType.Domain, "abc.in");
    UserPrincipal user = new UserPrincipal(domainContext)
    {
        GivenName = filter + "*"
    };

    PrincipalSearcher pS = new PrincipalSearcher
    {
        QueryFilter = user
    };

    PrincipalSearchResult<Principal> results = pS.FindAll();
    List<Principal> pc = results.ToList();
    foreach (Principal p in pc)
    {
        DirectoryEntry de = (DirectoryEntry)p.GetUnderlyingObject();
        if (de.Properties["givenName"].Value != null && de.Properties["sn"].Value != null)
            users.Add(de.Properties["givenName"].Value + " " + de.Properties["sn"].Value);
    }

    return users;
}

Я не думаю, что при использовании System.DirectoryServices.AccountManagement возникнет какая-либо проблема с производительностью, и она отлично работает для меня.Тем не менее я отметил ответ Габриэля как правильный ответ (идея применения фильтра).

0 голосов
/ 11 декабря 2018

В вашем коде есть пара проблем:

  1. Вы не фильтруете пользователей.Таким образом, этот код находит каждого пользователя в вашем домене каждый раз, когда вы запускаете его.Вы можете изменить это, используя текст, который пользователь уже ввел в качестве фильтра, и ограничив количество возвращаемых результатов (нет смысла отображать более 100 имен в элементе управления автозаполнением)
  2. PrincipalSearcherи все пространство имен System.DirectoryServices.AccountManagement не очень эффективно.Например, в этом случае он загружает каждый атрибут для каждого результата, найденного за кулисами, даже если вы используете только имя и фамилию.Вы можете добиться большего успеха, напрямую используя пространство имен System.DirectoryServices (DirectorySearcher / DirectoryEntry, которое в любом случае использует пространство имен AccountManagement).

Вот пример, которыйдолжно работать в вашем случае:

public List<string> ADUsers(string filter) {
    if (string.IsNullOrEmpty(filter)) throw new ArgumentNullException(nameof(filter));

    List<string> users = new List<string>();
    var ds = new DirectorySearcher(
        new DirectoryEntry("LDAP://abc.in"), //domain to search
        $"(&(objectClass=user)(anr={filter}))", //search filter
        new[] { "givenName", "sn" }) //attributes to load
    {
        SizeLimit = 25 //change this depending on how many you want to show
    };

    using (var results = ds.FindAll()) {
        foreach (SearchResult result in results) {
            users.Add($"{result.Properties["givenName"][0]} {result.Properties["sn"][0]}");
        }
    }
    return users;
}

Вы можете передать любое частичное имя как filter, и оно использует функцию в AD, называемую Разрешение неоднозначных имен , для поиска пользователей.Это будет искать частичные совпадения в имени, фамилии и других атрибутах (полный список в этой документации).

Я также ограничил результаты до 25, но вы можете изменить это по своему усмотрению.

Этот метод также указывает AD только возвращать атрибуты givenName и sn для каждого результата, так как это все, что нас волнует.Это уменьшит объем сетевого трафика между вашим приложением и контроллером домена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...