C# для профессионалов. Том II - Симон Робинсон
Шрифт:
Интервал:
Закладка:
Каждый объект имеет уникальный идентификатор — GUID. GUID является уникальным 128-битовым числом. Мы можем с соединиться с объектом, используя GUID. Таким образом, мы всегда получаем тот же самый объект, даже если объект был перемещен в другой контейнер. GUID генерируется при создании объекта и всегда остается тем же самым.
Можно получить строковое представление GUID с помощью DirectoryEntry.NativeGuid. Затем это строковое представление можно использовать для соединения с объектом. Даже если объект перемещается в другой контейнер, мы всегда получаем тот же объект.
Следующий пример показывает имя пути доступа для связывания без сервера со специфическим объектом, представленным GUID:
LDAP://<GUID=14abbd652aae1a47abc60782dcfc78ea>
Имена объектов в доменах Windows NTПровайдер WinNT не допускает синтаксис LDAP в части имени строки связывания. Для этого провайдера объект определяется с помощью ObjectName, ClassName. Действительные строки связывания для домена Windows NT имеют следующий вид:
WinNT:
WinNT://DomainName
WinNT://DomairName/UserName, user
WinNT://DomainName/dc01/MyGroup, group
Имя пользователя
Если другой пользователь, отличный от зарегистрированного, должен использоваться для доступа к каталогу, так как зарегистрированный пользователь не имеет требуемых полномочий для доступа к активному каталогу, то должны определяться явные полномочия пользователя для процесса связывания. Для активного каталога имеется ряд способов задания имени пользователя.
Низкоуровневая регистрацияДля низкоуровневой регистрации имя пользователя можно определить с помощью имени домена:
domainusername
Известное имяПользователя можно определить также с помощью известного имени объекта пользователя, например:
CN=Administrator, CN=Users, DC=eichkogelstrasse, DC=local
Имя пользователя принципала (UPN)UPN объекта определяется с помощью атрибута userPrincipalName. Системный администратор определяет его по информации регистрации на вкладке Account свойств User с помощью утилиты Active Directory Users and Computers. UPN не является адресом e-mail пользователя
Эта информация также уникальным образом определяет пользователя и может использоваться для регистрации:
[email protected]
Аутентификация
Для безопасной зашифрованной аутентификации можно также определить тип аутентификации. Аутентификация может задаваться с помощью свойства AuthenticationType класса DirectoryEntry. При этом присваиваемое значение является одним из перечислений AuthenticationTypes.
Связывание с помощью класса DirectoryEntry
Класс System.DirectoryServices.DirectoryEntry используется для определения всех связываемых данных. Можно использовать конструктор по умолчанию и определить данные связывания со свойствами Path, Username, Password и AuthenticationType или передать всю информацию в конструктор:
using (DirectoryEntry de = new DirectoryEntry()) {
de.Path = "LDAP://celticrain/DC=eichkogelstrasse, DC=local";
de.Username = "[email protected]";
de.Password = "someSecret";
// использовать полномочия текущего пользователя
DirectoryEntry de2 = new DirectoryEntry("LDAP://DC=eichkogelstrasse, DC=local");
Даже если создание объекта DirectoryEntry пройдет успешно, это не означает, что и связывание было успешным. Связывание произойдет, когда в первый раз будет прочитано свойство во избежание ненужного сетевого трафика. Существует ли объект или правильны ли полномочия определенного пользователя, можно будет увидеть при первом доступе к объекту.
Получение записей каталога
Теперь, когда мы знаем, как определить атрибута связывания с объектом в активном каталоге, давайте прочитаем атрибуты объекта.
Свойства объектов пользователей
Класс DirectoryEntry имеет некие свойства Name, Guid и SchemaClassName для получения информации об объекте. Первый раз при доступе к свойству объекта DirectoryEntry происходит связывание и заполняется кэш. Когда мы обращаемся к другому свойству, мы считываем его из кэша, и коммуникации с сервером не требуется для данных из того же объекта.
В следующем примере мы обращаемся к объекту пользователя с общим именем Christian Nagel в организационной единице Wrox Press.
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://celticrain/CN=Christian Nagel, " +
"OU=Wrox Press, DC=eichkogelstrasse, DC=local";
Console.WriteLine("Name: "+ de.Name);
Console.WriteLine("GUID: " + de.Guid);
Console.WriteLine("Type: " + de.SchemaClassName);
Console.WriteLine();
Объект активного каталога содержит значительно больше информации. Доступность информации зависит от типа объекта. Чтобы получить всю информацию об объекте, свойство Properties возвращает PropertyCollection. Каждое свойство само является коллекцией, так как одно свойство может иметь несколько значений, например, объект пользователя может иметь несколько телефонных номеров. Мы перебираем значения с помощью внутреннего цикла foreach. Коллекция, которая возвращается из properties[name] является массивом объектов. Значения атрибутов могут быть строками, числами или другими типами данных. Мы используем метод ToString() для вывода значений.
Console.WriteLine("Attributes: ");
PropertyCollection properties = de.Properties;
foreach (string name in properties.PropertyNames) {
foreach (object о in properties[name]) {
Console.WriteLine(name + ": " + o.ToString());
}
}
В выходных результатах мы видим все атрибуты объекта пользователя Christian Nagel. Заметим, что otherTelephone является многозначным свойством, которое содержит несколько телефонных номеров. Некоторые из значений свойств просто выводят тип объекта System._ComObject. Чтобы получить значения этих атрибутов, необходимо непосредственно использовать интерфейсы ADSI COM, которые также берутся из классов в пространстве имен System.DirectoryServices.
В главе 19 можно прочитать, как работать с объектам и и интерфейсами COM.
Для получения дополнительной информации об ADSI можно прочитать книгу Simon Robinson, Professional ADSI Programming, Wrox Press, ISBN 1-861002-26-2.
Доступ к свойствам непосредственно по имениС помощью DirectoryEntry.Properties можно получить доступ ко всем свойствам. Если имя свойства известно, можно получить значение непосредственно:
foreach (string homePage in de.Properties["wWWHomePage"])
Console.WriteLine("Home page; " + homePage);
Коллекции объектов
Объекты хранятся в активном каталоге иерархически. В контейнерных объектах содержатся объекты-потомки. Их можно перечислить с помощью свойства Children класса DirectoryEntry. В другом направлении можно получить контейнер объекта с помощью свойства Parent.
Объект пользователя не имеет потомков, поэтому воспользуемся теперь организационной единицей. Давайте получим все объекты пользователей из организационной единицы Wrox Press в домене eichkogelstrasse.local. Свойство Children возвращает коллекцию DirectoryEntries, которая содержит объекты DirectoryEntry. Мы просматриваем все объекты DirectoryEntry для вывода имен объектов-потомков:
DirectoryEntry de = new DirectoryEntry();
de.Path. = "LDAP://celticrain/OU=Wrox Press, " + "DC=eichkogelstrasse, DC=local";
Console.WriteLine("Children of " + de.Name);
foreach (DirectoryEntry obj in de.Children) {
Console.WriteLine(obj.Name);
}
В данном примере мы видим все объекты в организационной единице: пользователей, контакты, принтеры, общие ресурсы и другие организационные единицы. Если нужно увидеть только некоторые типы объектов, можно использовать свойство SchemaFilter класса DirectoryEntries:
DirectoryEntry de = new DirectoryEntry();
de.Path = "LDAP://celticrain/OU=Wrox Press, " + "DC=eichkogelstrasse, DC-local";
Console.WriteLine("Children of " + de.Name);
de.Children.SchemaFilter.Add("user");
foreach(DirectoryEntry obj in de.Children) {
Console.WriteLine(obj.Name);
}
В результате мы видим в организационной единице только объекты пользователей:
Кэш
Чтобы уменьшить сетевой трафик, ADSI использует кэш для свойств объектов. Как было показано ранее, обращение к серверу не происходит при создании объекта DirectoryEntry, а происходит, когда впервые считывается значение из хранилища каталога. При считывании первого свойства все свойства записываются в кэш, поэтому повторное обращение к серверу не нужно, когда считывается следующее свойство. Этот кэш свойств может быть выключен при задании свойства DirectoryEntry.UsePropertyCache как false. Лучше этого не делать, так как это будет порождать множество ненужных обращений к серверу.