Сбой простой привязки к AD-LDS с удаленного компьютера

Я использую API System.DirectoryServices.AccountManagement для привязки к экземпляру AD-LDS. Я использую простую привязку с пользователем, существующим локально в экземпляре AD-LDS. Это работает, когда я запускаю клиент на сервере, на котором размещается AD-LDS, но не работает, когда я запускаю клиент на удаленном компьютере.

Это код, который я использую для привязки и поиска пользователя:

var c = new PrincipalContext(ContextType.ApplicationDirectory, "fullhostname:50001", "CN=Users,DC=app,DC=local", ContextOptions.SimpleBind, "CN=joe,CN=Users,DC=app,DC=local", "abc");
var u = UserPrincipal.FindByIdentity(c, IdentityType.Name, "john");

Это исключение, которое выдается, когда я запускаю его на удаленном компьютере:

System.DirectoryServices.AccountManagement.PrincipalServerDownException: The server is not operational.
---> System.Runtime.InteropServices.COMException: The server is not operational.
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectoryEntry.get_Options()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
   --- End of inner exception stack trace ---
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoApplicationDirectoryInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_ConnectedServer()
   at MyApplication.DiagnosticsController.TryAdLdsSettings(AdLdsData data) in C:\code\MyApplication\DiagnosticsController.cs:line 166

Если вместо этого я использую API System.DirectoryServices, он также работает с удаленного компьютера:

var obj = new DirectoryEntry("LDAP://fullhostname:50001/CN=Users,DC=app,DC=local", "CN=joe,CN=Users,DC=app,DC=local",
                "abc", AuthenticationTypes.None);
obj.RefreshCache();

Это работает, но вместо этого мне нужно использовать System.DirectoryServices.AccountManagement API.

Кто-нибудь знает, что не так?


person kls    schedule 12.05.2015    source источник
comment
клс, есть прогресс или решение? Я чувствую, что я испытываю ту же проблему здесь.   -  person pettys    schedule 27.02.2016
comment
@petty - можете ли вы отредактировать вопрос с полным исключением или опубликовать ответ без ответа с более подробной информацией? Внутри PrincipleServerDownException должно быть исключение LdapException с дополнительной информацией о характере сбоя.   -  person antiduh    schedule 29.02.2016
comment
@antiduh Я отредактировал вопрос, добавив дополнительную информацию (в настоящее время на рассмотрении). К сожалению, я не вижу LdapException - только COMException.   -  person pettys    schedule 29.02.2016


Ответы (2)


Мне удалось заставить это работать на домене с несколькими незначительными изменениями, надеюсь, эти советы помогут.

  1. Ваш предпоследний параметр при создании PrincipalContext, "CN=joe,CN=Users,DC=app,DC=local", должен быть полным именем пользователя, а не путем LDAP; обычно это будет выглядеть как COMPUTER-NAME\\joe (как бы ни назывался ваш компьютер) или, если вы находитесь в домене, как и я, DOMAIN-NAME\\joe. (Если fullhostname не является вашей локальной рабочей станцией, то вы можете быть в домене, или вам может потребоваться указать fullhostname\joe для запроса аутентификации на хост-сервере, а не на локальном, поскольку ваши локальные учетные данные, вероятно, не будут работать на хосте. сервер).

  2. Для тестирования этого в домене мне пришлось изменить первый параметр с ContextType.ApplicationDirectory на ContextType.Domain; похоже, что вы не в домене, поэтому вам, вероятно, понадобится ContextType.ApplicationDirectory, но сообщение об ошибке заставляет меня думать, что службы Active Directory не запущены.

  3. Поскольку :50001 достаточно велико, чтобы его можно было заблокировать, убедитесь, что у вас нет программного обеспечения брандмауэра, которое блокирует запрос, исходящий с вашего компьютера или входящий на компьютер с полным именем хоста; и, конечно же, убедитесь, что ваши службы Active Directory действительно доступны на 50001, а не на каком-либо другом протоколе аутентификации.

person Matt Jordan    schedule 29.02.2016
comment
Re 1: имя пользователя в стиле различающегося имени работает с настройкой разработки. Предлагаемые вами стили имени пользователя подходят для ContextType.Domain и ContextType.Machine. Относительно 2: мы подключаемся к ADLDS, а не к обычной AD, поэтому ContextType.ApplicationDirectory, безусловно, подходит для нашего сценария. Re 3: Мы пробовали стандартные 389 (без SSL) и 636 (SSL) с тем же результатом. Кроме того, мы можем успешно привязаться к AD LDS с веб-сервера с помощью ADSI Edit с указанными параметрами. - person pettys; 29.02.2016

В итоге я переписал свои варианты использования PrincipalContext и UserIdentity, чтобы использовать вместо них напрямую DirectoryEntry. Мне потребовалось несколько часов, чтобы найти подходящие реализации для нужных мне удобных UserIdentity функций, но после этого все заработало нормально.

Для меня довольно загадка, почему проблема возникла в первую очередь. Мое единственное предположение состоит в том, что с моей конкретной версией AD LDS в моей конкретной конфигурации есть ошибка где-то в базовых библиотеках. Переписав все прямо в DirectoryEntry, сделав все максимально похожим на то, что я умею делать, я решил проблему.

person pettys    schedule 07.03.2016