найти доменное имя, используя адрес электронной почты из Active Directory - PullRequest
0 голосов
/ 23 апреля 2020

Я в организации, где человек может иметь несколько адресов электронной почты, например,

, если пользователь alias = alias1, он наверняка будет иметь один адрес электронной почты как alias1@org.com, в то же время он может иметь другой адрес электронной почты fname . lname123@org.com

Также у моей организации есть несколько активных доменов каталогов, таких как Северная Америка, EASTASIA и др. c.

Я хочу узнать, к какому домену активных каталогов принадлежит пользователь. Используя приведенный ниже код, я могу определить домен для всех писем типа alias@org.com, но для других типов писем код не может найти запись в активном каталоге.

    string[] emails = new string[]{"alias1@org.com", "fname.lname@org.com"};
    string[] DOMAINS = new string[] { "DOMAIN1", "DOMAIN2"};
    PrincipalContext[] contexts = new PrincipalContext[DOMAINS.Length];
    for (int i=0; i<DOMAINS.Length; i++)
    {
        contexts[i] = new PrincipalContext(ContextType.Domain, DOMAINS[i]);
    }
    foreach (string email in emails)
    {
        string myDomain = "Not found";
        for(int i=0; i<DOMAINS.Length; i++)
        {

            UserPrincipal yourUser = UserPrincipal.FindByIdentity(contexts[i], email);

            if (yourUser != null)
            {
                myDomain = DOMAINS[i];'
                break;
            }
        }
        Console.WriteLine(email + " " + myDomain);

    }

для alias1@org.com я был удалось найти домен активного каталога, но не для другого случая

1 Ответ

1 голос
/ 23 апреля 2020

UserPrincipal.FindByIdentity() не может осуществлять поиск по адресу электронной почты. Поиск возможен только по одному из типов идентификаторов в IdentityType. В вашем случае это, вероятно, совпадение по UserPrincipalName, поэтому иногда вы найдете результаты, но не все.

Для этого я бы использовал DirectorySearcher напрямую, то есть то, что UserPrincipal.FindByIdentity() использует за в любом случае, но у вас больше контроля над поиском.

Вам придется искать по атрибуту proxyAddresses. Там будут все адреса электронной почты пользователя с префиксом smtp: (основной адрес - прописные буквы SMTP:). Это будет выглядеть примерно так:

string[] emails = new string[]{"alias1@org.com", "fname.lname@org.com"};
string[] DOMAINS = new string[] { "DOMAIN1", "DOMAIN2"};
foreach (string email in emails)
{
    string myDomain = "Not found";
    for(int i=0; i<DOMAINS.Length; i++)
    {

        var searcher = new DirectorySearcher {
            SearchRoot = new DirectoryEntry($"LDAP://{DOMAINS[i]}"),
            Filter = $"(&(objectClass=user)(objectCategory=person)(proxyAddresses=smtp:{email}))",
            PropertiesToLoad = { "cn" } //just put something so it doesn't return everything
        };

        if (searcher.FindOne() != null)
        {
            myDomain = DOMAINS[i];
            break;
        }
    }
    Console.WriteLine(email + " " + myDomain);
}

Если все домены, которые вы ищете, находятся в одном лесу AD, вы можете сэкономить время, выполнив один раз запрос к Глобальному каталогу, а не разделять запросы на каждый домен. Глобальный каталог хранит данные для всех доменов в лесу. Вы выбираете Глобальный каталог, используя GC:// вместо LDAP://.

Затем вы можете запросить атрибут пользователя msDS-PrincipalName, который будет именем пользователя в формате DOMAIN\username , так что вы можете извлечь доменное имя из этого. Например:

string[] emails = new string[]{"alias1@org.com", "fname.lname@org.com"};
foreach (string email in emails)
{
    string myDomain = "Not found";
    var searcher = new DirectorySearcher {
        SearchRoot = new DirectoryEntry("GC://example.com"),
        Filter = $"(&(objectClass=user)(objectCategory=person)(proxyAddresses=smtp:{email}))",
        PropertiesToLoad = { "msDS-PrincipalName" }
    };

    var found = searcher.FindOne();
    if (found != null)
    {
        var mdDsPrincipalName = (string) found.Properties["msDS-PrincipalName"][0];
        myDomain = mdDsPrincipalName.Substring(0, mdDsPrincipalName.IndexOf("\\"));
    }
    Console.WriteLine(email + " " + myDomain);
}

Просто замените example.com именем любого из ваших доменов (неважно, какой).

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