4

我正在使用 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

如果我改为使用 System.DirectoryServices API,它也可以在远程计算机上工作:

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。

有谁知道出了什么问题?

4

2 回答 2

0

我最终改写了我的用法PrincipalContext并直接UserIdentity使用DirectoryEntry。我花了几个小时为UserIdentity我需要的便捷功能找到合适的重新实现,但这样做之后一切正常。

对我来说,为什么首先会出现这个问题是个谜。我唯一的猜测是,在我的特定配置中使用特定版本的 AD LDS 时,底层库中的某处存在错误。直接在 中重写所有内容DirectoryEntry,使所有内容与我知道的完全相似,从而解决了问题。

于 2016-03-07T16:23:28.327 回答
0

通过一些小的改动,我能够让它在一个域上工作,我希望这些技巧能有所帮助。

  1. 创建 PrincipalContext 时的倒数第二个参数"CN=joe,CN=Users,DC=app,DC=local"应该是完全限定的用户名,而不是 LDAP 路径;这通常看起来像COMPUTER-NAME\\joe(无论您的计算机被命名为什么),或者如果您像我一样在域中,DOMAIN-NAME\\joe. (如果 fullhostname 不是您的本地工作站,那么您可能在域中,或者您可能需要指定 fullhostname\joe 来请求针对主机服务器而不是本地服务器的身份验证,因为您本地的凭据可能无法在主机上工作服务器)。

  2. 为了在域上进行测试,我必须将第一个参数从 更改ContextType.ApplicationDirectoryContextType.Domain; 听起来您不在域中,因此您可能需要ContextType.ApplicationDirectory,但错误消息让我认为 Active Directory 服务没有运行。

  3. 由于:50001高到足以被阻止,请确保您没有阻止请求的防火墙软件,无论是从您的机器传出,还是传入“fullhostname”机器;当然,请确保您的活动目录服务在 50001 上实际可用,而不是其他一些身份验证协议。

于 2016-02-29T16:10:33.010 回答