Имея доступ к Active Directory, могу ли я получить GUID объекта для пользователя только по имени пользователя / адресу электронной почты? - PullRequest
1 голос
/ 01 октября 2019

Фон

Я экспериментировал с доступом к активному каталогу в C #, чтобы узнать, как подключать / проверять учетные данные различными способами. В нижней части этого ответа я включил несколько фрагментов кода, чтобы дать представление о том, что я сделал, может быть, это может быть построено для достижения моей цели.

Основная цель

Если у меня есть действительные учетные данные для подключения к Active Directory, могу ли я взять строку, представляющую имя пользователя / адрес электронной почты (при условии, что она существует в userPrincipalName или аналогичном поле), и получить обратно objectGUID?

Или мне нужно принимать во внимание другие вещи, такие как: разрешения, которые эти полномочия имеют для поиска других пользователей;знание структуры различных AD;если userPrincipalName является правильным полем для поиска?

Фрагменты кода (экспериментальные начала, не полностью функциональные для моей цели)

var credentials = new NetworkCredential(username, password, hostname);
var serverId = new LdapDirectoryIdentifier(hostname);
var connection = new LdapConnection(serverId, credentials);
try
{
    connection.Bind();
}
catch (Exception e)
{
    //error
    Console.WriteLine(e);
    connection.Dispose();
    return;
}
//success

var dirEntry = new DirectoryEntry(string.Format("LDAP://{0}/{1}", hostname, baseDn), username, password);
var searcher = new DirectorySearcher(dirEntry)
{
    Filter = "(&(&(objectClass=user)(objectClass=person)))"
};
var resultCollection = searcher.FindAll();
searcher.Dispose();

1 Ответ

1 голос
/ 02 октября 2019

Вы на правильном пути с DirectorySeacher. Вам просто нужен правильный запрос и несколько других настроек.

  1. Измените Filter, чтобы найти то, что вы ищете.

    a. Если у вас есть адрес электронной почты:

    • (&(objectClass=user)(objectClass=person)(mail=email@example.com))
    • или (&(objectClass=user)(objectClass=person)(proxyAddresses=smtp:email@example.com)) (это будет совпадать и с дополнительными адресами электронной почты)

    b,Если у вас есть имя пользователя, это зависит от того, какое имя пользователя у вас есть.

    • Основное имя пользователя: (&(objectClass=user)(objectClass=person)(userPrincipalName=username@example.com))
    • То, что обычно называется «именем пользователя», которое часто форматируется как DOMAIN. \ username: (&(objectClass=user)(objectClass=person)(sAMAccountName=myusername))
  2. Использование DirectorySeacher.PropertiesToLoad. Если вы этого не сделаете, он будет извлекать каждый атрибут со значением , который является просто потраченным впустую сетевым трафиком.

  3. Вам не нужно утилизировать DirectorySearcher, но вам нужно утилизировать resultCollection, поскольку в документации говорится, что вы можете получить утечку памяти, если оставите ее для сборки мусора.

Итак, если у вас есть userPrincipalName, у вас будет что-то вроде этого:

var userToLookFor = "username@example.com";
var dirEntry = new DirectoryEntry(string.Format("LDAP://{0}/{1}", hostname, baseDn), username, password);
var searcher = new DirectorySearcher(dirEntry)
{
    Filter = $"(&(objectClass=user)(objectClass=person)(userPrincipalName={userToLookFor}))",
    SizeLimit = 1 //we're only looking for one account
};
searcher.PropertiesToLoad.Add("objectGuid");

using (var resultCollection = searcher.FindAll())
{
    if (resultCollection.Count == 1)
    {
        var userGuid = new Guid((byte[]) resultCollection[0].Properties["objectGuid"][0]);
    }
    else
    {
        //the account was not found - do something else
    }
}

...