Я придумал это решение проблемы.
Для поддержки нескольких доменов, как в доверительных отношениях, так и даже в изолированных сетях, в первую очередь я добавил NameValueCollection в мой web.config, чтобы вывести список доменов и их контроллеров доменов.
<domains>
<add key="domain1" value="10.0.0.1"/>
<add key="domain2" value="10.0.1.11"/>
</domains>
(более подробная информация о конфигурации добавлена в , поэтому вопрос )
Затем следующим шагом было чтение домена из учетных данных пользователя, как я упомянул в вопросе. Получив домен, я пытаюсь найти соответствующий контроллер домена по значениям конфигурации, чтобы получить правильную строку подключения LDAP. Итак, мой метод таков:
private string GetLDAPConnection(string a_Domain, string a_Username, string a_Password)
{
// Get the domain controller server for the specified domain
NameValueCollection domains = (NameValueCollection)ConfigurationManager.GetSection("domains");
string domainController = domains[a_Domain.ToLower()];
string ldapConn = string.Format("LDAP://{0}/rootDSE", domainController);
DirectoryEntry root = new DirectoryEntry(ldapConn, a_Username, a_Password);
string serverName = root.Properties["defaultNamingContext"].Value.ToString();
return string.Format("LDAP://{0}/{1}", domainController, serverName);
}
Как только я получаю правильную строку подключения, я делаю новый вызов для аутентификации пользователя, обращаясь к соответствующему LDAP
...
string ldapConn = GetLDAPConnection(domain, username, a_Password);
DirectoryEntry entry = new DirectoryEntry(ldapConn, username, a_Password);
try
{
try
{
object obj = entry.NativeObject;
}
catch(DirectoryServicesCOMException comExc)
{
LogException(comExc);
return false;
}
DirectorySearcher search = new DirectorySearcher(entry);
search.Filter = string.Format("(SAMAccountName={0})", username);
search.PropertiesToLoad.Add("cn");
SearchResult result = search.FindOne();
С этого момента я также могу выполнять все остальные запросы, такие как членство пользователя в группе и т. Д.
Поскольку вызов к удаленным доменам должен быть привязан к пользователю, я использую учетные данные «вызывающих» пользователей. Таким образом, пользователь получает аутентификацию, и вызов привязывается к конкретному пользователю. Кроме того, я указываю домен по умолчанию для случаев, когда пользователи предоставляют свои учетные данные без указания домена.
Мне не удалось этого, однако, используя PrincipalContext, как я хотел, но, с другой стороны, это решение применимо и к более старым приложениям .NET 2.0.
Я не уверен, что это лучшее решение проблемы, однако, похоже, оно работает в тестах, которые мы до сих пор проводили.