Я в настоящее время пытаюсь пройти проверку подлинности через Active Directory Services с помощью класса PrincipalContext. Я хотел бы иметь свое приложение, проходят проверку подлинности к Изолированному использованию Домена и контексты SSL. Чтобы сделать это, я должен использовать следующего конструктора PrincipalContext (свяжитесь со страницей MSDN):
public PrincipalContext(
ContextType contextType,
string name,
string container,
ContextOptions options
)
А именно, я использую конструктора в качестве так:
PrincipalContext domainContext = new PrincipalContext(
ContextType.Domain,
domain,
container,
ContextOptions.Sealing | ContextOptions.SecureSocketLayer);
MSDN заявляет о "контейнере":
Контейнер на хранилище для использования в качестве корня контекста. Все запросы выполняются под этим корнем и всеми, какие вставки выполняются в этот контейнер. Для типов контекста Домена и ApplicationDirectory этот параметр является отличительным именем (DN) контейнерного объекта.
Каков DN контейнерного объекта? Как я узнаю, каков мой контейнерный объект? Я могу запросить Active Directory (или LDAP) сервер для этого?
Что ж, мне удалось выяснить проблему:
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain);
domainContext.ValidateCredentials(userName, password,
ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
Указав ContextOptions в методе ValidateCredentials (а не в конструкторе), это позволило мне чтобы избежать необходимости указывать DN для объекта-контейнера.
ОБНОВЛЕНИЕ:
Хотя я должен уточнить, что после дальнейших экспериментов я обнаружил, что любые запросы, производные от этого объекта PrincipalContext, имеют UN-шифрование.
Очевидно, когда ContextOptions заданы в ValidateCredentials, эти параметры используются только для этого конкретного вызова ValidateCredentials. Но вот где это становится странным ...
Итак, я хотел, чтобы мои запросы к серверу AD также выполнялись зашифрованными. Пример запроса:
UserPrincipal p = UserPrincipal.FindByIdentity(
domainContext, IdentityType.SamAccountName, userName);
var groups = p.GetGroups();
foreach (GroupPrincipal g in groups) { /* do something */ }
Приведенный выше код получает список всех групп, к которым принадлежит пользователь, но это происходит в незашифрованном виде. Итак, после долгой игры я обнаружил, что DN никогда не нужно устанавливать.
PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain,
null,ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
Я обнаружил, что могу установить объект-контейнер (DN) равным нулю. И это прекрасно работает. Установка его на пустую строку ("") приводит к исключению какого-то неизвестного типа, поэтому не думайте, что вы можете дать ему пустую строку.
И вот что самое странное. Вы могли подумать, что установка параметра SecureSocketLayer в PrincipalContext будет означать, что вам не нужно явно устанавливать его при использовании VerifyCredentials. Но я обнаружил, что если я не установил его в части VerifyCredentials, аутентификация не удалась бы, но запросы (как в примере с группами) по-прежнему выполняются в зашифрованном виде.
Возможно, я просто еще не до конца понимаю аутентификацию и запросы AD, но мне это кажется странным.