Правильный способ поиска пользователя AD по адресу электронной почты из .NET - PullRequest
11 голосов
/ 29 марта 2010

У меня возникли некоторые проблемы с кодом, который предназначен для поиска пользователя в Active Directory путем поиска по его адресу электронной почты. Я пробовал 2 метода, но иногда обнаруживаю, что метод FindOne () в некоторых случаях не возвращает никаких результатов. Если я смотрю пользователя в GAL в Outlook, я вижу SMTP-адрес электронной почты в списке.

Моя конечная цель - подтвердить, что пользователь существует в AD. У меня есть только адрес электронной почты в качестве критерия поиска, поэтому нельзя использовать имя или фамилию.

Способ 1. Использование свойства mail:

DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(mail=" + email + ")";
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne();

Метод 2: свойство proxyAddresses:

DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = "(proxyAddresses=SMTP:" + email + ")"; // I've also tried with =smtp:
search.PropertiesToLoad.Add("mail");
SearchResult result = search.FindOne();

Я попытался изменить регистр ввода адреса электронной почты, но он по-прежнему не возвращает результат. Есть ли здесь проблема с чувствительностью к регистру? Если да, то как лучше всего это решить?

Ответы [ 3 ]

13 голосов
/ 02 апреля 2010

Если вы используете Exchange Server, proxyAddresses является наиболее надежным средством получения своего адреса электронной почты. Основной адрес SMTP указывается всеми заглавными буквами «SMTP:», а дополнительные адреса электронной почты будут иметь префикс «smtp:» в нижнем регистре. Атрибут «mail» не обязательно должен быть основным SMTP-адресом, хотя обычно это так.

Вот вариант кода, который я использовал:

    public static SearchResult FindAccountByEmail(string email)
    {
        string filter = string.Format("(proxyaddresses=SMTP:{0})", email);

        using (DirectoryEntry gc = new DirectoryEntry("GC:"))
        {
            foreach (DirectoryEntry z in gc.Children)
            {
                using (DirectoryEntry root = z)
                {
                    using (DirectorySearcher searcher = new DirectorySearcher(root, filter, new string[] { "proxyAddresses", "objectGuid", "displayName", "distinguishedName" }))
                    {
                        searcher.ReferralChasing = ReferralChasingOption.All;
                        SearchResult result = searcher.FindOne();

                        return result;
                    }
                }
                break;
            }
        }

        return null;
    }

    static void Main(string[] args)
    {
        SearchResult result = FindAccountByEmail("someone@somewhere.com");

        string distinguishedName = result.Properties["distinguishedName"][0] as string;
        string name = result.Properties["displayName"] != null
                        ? result.Properties["displayName"][0] as string
                        : string.Empty;
        Guid adGuid = new Guid((byte[]) (result.Properties["objectGUID"][0]));

        string emailAddress;
        var emailAddresses = (from string z in result.Properties["proxyAddresses"]
                              where z.StartsWith("SMTP")
                              select z);
        emailAddress = emailAddresses.Count() > 0 ? emailAddresses.First().Remove(0, 5) : string.Empty;


        Console.WriteLine(string.Format("{1}{0}\t{2}{0}\t{3}{0}\t{4}",
                      Environment.NewLine,
                      name,
                      distinguishedName,
                      adGuid,
                      emailAddress));
    }
4 голосов
/ 06 апреля 2010

Я обнаружил, что использование SysInternals ADExplorer отлично подходит для тестирования / отладки запросов Active Directory. Поскольку вы можете создавать запросы и запускать их в Active Directory, вы можете видеть результаты, а также легко просматривать объекты и видеть все их свойства ...

0 голосов
/ 02 апреля 2010

У меня никогда не было проблем с чувствительностью к регистру при поиске адресов электронной почты пользователей - что произойдет, если вы будете искать адрес в точности так, как он отображается в ADSIEDIT? Находит ли он адрес, когда он правильно указан?

Кстати, я всегда использовал свойство mail, поскольку оно возвращает единственный исходящий адрес электронной почты пользователя по умолчанию, даже если к учетной записи подключено несколько адресов. Свойство «proxyAddresses» на самом деле является многозначным свойством, и вы просто ищете значение, которое начинается с «smtp:» (это свойство в нижнем регистре). Однако пользователь может иметь несколько SMTP-адресов в своей учетной записи AD (мы делаем это), поэтому между ними может быть свойство «mail».

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