【问题标题】:Simple bind to AD-LDS fails from remote computer从远程计算机简单绑定到 AD-LDS 失败
【发布时间】:2015-05-12 14:48:54
【问题描述】:

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

有谁知道怎么回事?

【问题讨论】:

  • kls,有什么进展或解决方案吗?我觉得我在这里遇到了同样的问题。
  • @petty - 您可以编辑完整例外的问题,还是发布包含更多详细信息的非答案答案? PrincipleServerDownException 中应该有一个 LdapException,其中包含有关失败性质的更多信息。
  • @antiduh 我用更多信息编辑了这个问题(目前正在同行评审中)。不幸的是,我没有看到 LdapException - 只是一个 COMException。

标签: c# .net directoryservices account-management adlds


【解决方案1】:

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

  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. 1234563当然,还要确保您的 Active Directory 服务在 50001 上实际可用,而不是其他一些身份验证协议。

【讨论】:

  • Re 1:专有名称样式的用户名适用于开发设置。您建议的用户名样式适用于ContextType.DomainContextType.Machine。回复 2:我们正在连接到 ADLDS,而不是常规 AD,所以 ContextType.ApplicationDirectory 在我们的场景中肯定是正确的。回复 3:我们尝试使用标准 389(非 SSL)和 636(SSL),结果相同。此外,我们可以使用如图所示的参数使用 ADSI Edit 从 Web 服务器成功绑定到 AD LDS。
【解决方案2】:

我最终重写了 PrincipalContextUserIdentity 的用法,直接使用 DirectoryEntry。我花了几个小时才为我需要的方便的UserIdentity 函数找到合适的重新实现,但这样做之后一切正常。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    相关资源
    最近更新 更多