UserPrincipal.FindByIdentity 坚持“服务器上没有这样的对象。”

发布于 2024-12-14 15:53:06 字数 3192 浏览 5 评论 0原文

我目前的目标是使用 System.DirectoryServices.AccountManagement 程序集中的实用程序为基于域安全组的 ASP.NET 应用程序实现只读角色提供程序。我有以下一段代码,它在我的开发域中运行良好,但在部署环境中失败:

Using myContext As New PrincipalContext(ContextType.Domain, Nothing, "DC=My,DC=Controller", accountName, accountPassword)
    Try
        Dim p As UserPrincipal = UserPrincipal.FindByIdentity(myContext, IdentityType.SamAccountName, userName)
        Dim groups = p.GetAuthorizationGroups()
        For Each g In groups
            Debug.WriteLine("Found security group: " & g.DisplayName & vbNewLine)
        Next
    Catch ex As Exception
        Debug.WriteLine("Encountered an exception: " & vbNewLine & ex.ToString())
    End Try
End Using

异常堆栈跟踪返回如下:

    System.DirectoryServices.AccountManagement.PrincipalOperationException: There is no such object on the server.
     ---> System.DirectoryServices.DirectoryServicesCOMException (0x80072030): There is no such object on the server.
       at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
       at System.DirectoryServices.DirectoryEntry.Bind()
       at System.DirectoryServices.DirectoryEntry.get_SchemaEntry()
       at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)
       at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options)
       at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry)
       at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
       --- End of inner exception stack trace ---
       at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
       at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
       at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
       at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
       at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
       at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
       at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)

我知道这里明显的“陷阱”是要确定对象实际上,嗯......存在于服务器上。但是,我可以毫无疑问地确认,无论我使用哪个帐户的 SAM 帐户名,我都会从调用中收到相同的结果。此外,Microsoft 的 ActiveDirectoryMembershipProvider 对相同的 SAM 帐户名进行身份验证没有任何问题,并且我能够使用该信息与 DirectorySearcher 类。我可以识别的开发网络和部署之间的唯一区别是部署环境的 DC 是 Windows Server 2003 机器,而我在本地使用 Windows Server 2008 DC 进行开发。我可能会忽略什么?

I am currently aiming to implement a read-only role provider for an ASP.NET application based on domain security groups using the utilities in the System.DirectoryServices.AccountManagement assembly. I have the following piece of code which works fine on my development domain, but fails in the deployment environment:

Using myContext As New PrincipalContext(ContextType.Domain, Nothing, "DC=My,DC=Controller", accountName, accountPassword)
    Try
        Dim p As UserPrincipal = UserPrincipal.FindByIdentity(myContext, IdentityType.SamAccountName, userName)
        Dim groups = p.GetAuthorizationGroups()
        For Each g In groups
            Debug.WriteLine("Found security group: " & g.DisplayName & vbNewLine)
        Next
    Catch ex As Exception
        Debug.WriteLine("Encountered an exception: " & vbNewLine & ex.ToString())
    End Try
End Using

The exception stack trace returns as follows:

    System.DirectoryServices.AccountManagement.PrincipalOperationException: There is no such object on the server.
     ---> System.DirectoryServices.DirectoryServicesCOMException (0x80072030): There is no such object on the server.
       at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
       at System.DirectoryServices.DirectoryEntry.Bind()
       at System.DirectoryServices.DirectoryEntry.get_SchemaEntry()
       at System.DirectoryServices.AccountManagement.ADStoreCtx.IsContainer(DirectoryEntry de)
       at System.DirectoryServices.AccountManagement.ADStoreCtx..ctor(DirectoryEntry ctxBase, Boolean ownCtxBase, String username, String password, ContextOptions options)
       at System.DirectoryServices.AccountManagement.PrincipalContext.CreateContextFromDirectoryEntry(DirectoryEntry entry)
       at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
       --- End of inner exception stack trace ---
       at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
       at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
       at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
       at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
       at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
       at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
       at System.DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)

I know the obvious "gotcha" here is to be certain the object actually, well... exists on the server. However, I can confirm without a doubt that no matter which account's SAM Account Name I use, I receive the same result from the call. Additionally, Microsoft's ActiveDirectoryMembershipProvider has no trouble authenticating against the same SAM Account Name and I am able to find the object using that information with the DirectorySearcher class. The only differences I can identify between the development network and deployment is that the deployment environment's DC is a Windows Server 2003 box, whereas locally I am developing with a Windows Server 2008 DC. What might I be overlooking?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

古镇旧梦 2024-12-21 15:53:06

由于某种原因,问题出在域控制器的路径上。将路径描述为 DC=box123,DC=dom 不起作用,但使用路径 box123.dom 可以。不能说为什么,这不是我可以在本地域上复制的行为,但这解决了问题。

编辑:
经过进一步调查,构造 DC=box123,DC=dom 当简化为 DC=dom 时也能正常运行。我不了解寻址的动态,但我能够通过使用 DirectorySearcher 对象显示示例用户的路径来确定问题,该对象显示我的用户的路径为:LDAP://box123 .dom/CN=用户名/CN=用户/DC=dom

For some reason, the problem lay in the path to the domain controller. Describing the path as DC=box123,DC=dom did not work, but using the path box123.dom did. Can't say why, and it's not a behavior I can duplicate on the local domain, but that resolved the issue.

EDIT:
Upon further investigation, the construction DC=box123,DC=dom when pared down to DC=dom functioned correctly as well. I don't understand the dynamics of the addressing, but I was able to determine the trouble by displaying the path to a sample user using a DirectorySearcher object, which revealed the path to my user to be: LDAP://box123.dom/CN=username/CN=Users/DC=dom

国粹 2024-12-21 15:53:06

我知道这是一个相对较老的问题,但我认为我们的解决方案可能会帮助其他人。我们在客户的生活环境中也遇到了同样的问题。最初我们无法在测试环境中复制该问题,但后来我们发现只有在使用 https 访问站点时才会发生该问题。通过大量的试验和错误以及对 Microsoft 的支持呼叫,我开始尝试创建主要上下文的呼叫。最初,对象实例化被编码为

using (var pc = new PrincipalContext(ContextType.Domain, <serverUri>, <ldapDomain>, <username>, <userpass>))

完整的构造函数可以采用一个附加参数

using (var pc = new PrincipalContext(ContextType.Domain, <serverUri>, <ldapDomain>, ContextOptions.Negotiate, <username>, <userpass>))

一旦指定了ContextOption(在我们的例子中,它必须是Negotiate),调用UserPrincipal.FindByIdentity 按预期工作。

I know this is a relatively old question, but I thought our solution might help someone else down the line. We encountered the same issue in the customer's live environment. Initially we couldn't replicate the issue in our test environment, but then we discovered it only happened when accessing the site under https. Through a lot of trial and error plus a support call to Microsoft, I started playing around with the call to create the principal context. Initially, the object instantiation was coded as

using (var pc = new PrincipalContext(ContextType.Domain, <serverUri>, <ldapDomain>, <username>, <userpass>))

The full constructor can take one additional parameter

using (var pc = new PrincipalContext(ContextType.Domain, <serverUri>, <ldapDomain>, ContextOptions.Negotiate, <username>, <userpass>))

Once the ContextOption was specified (and in our case, it had to be Negotiate), the call to UserPrincipal.FindByIdentity worked as expected.

伴我老 2024-12-21 15:53:06

您不显示 dcPath 的值,这是一种像这样构造PrincipalContext 的方法。

Using myContext As New PrincipalContext ContextType.Domain, "dom.fr:389", "dc=dom,dc=fr", "jpb", "root.123");

此后,该异常可以通过以下事实来解释:userName 不是控制器上的有效 samAccountName。

You don't show th values of dcPath here is a way to construct PrincipalContext like this.

Using myContext As New PrincipalContext ContextType.Domain, "dom.fr:389", "dc=dom,dc=fr", "jpb", "root.123");

After that the exception can be explained by the fact that userName is not a valid samAccountName on your controler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文