我目前的目标是使用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进行开发。我可以俯瞰什么?
答案 0 :(得分:4)
由于某种原因,问题在于域控制器的路径。将路径描述为DC=box123,DC=dom
不起作用,但使用路径box123.dom
。不能说为什么,这不是我可以在本地域上复制的行为,但这解决了这个问题。
编辑:
经过进一步调查,结构DC=box123,DC=dom
在削减到DC=dom
时也能正常运行。我不了解寻址的动态,但我能够通过使用DirectorySearcher对象显示示例用户的路径来确定问题,该对象显示了我的用户的路径:LDAP://box123.dom/CN=username/CN=Users/DC=dom
答案 1 :(得分:2)
我知道这是一个相对陈旧的问题,但我认为我们的解决方案可能会帮助其他人。我们在客户的实时环境中遇到了同样的问题。最初我们无法在我们的测试环境中复制该问题,但后来我们发现它只在访问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
的调用按预期工作。
答案 2 :(得分:1)
你没有显示dcPath的值这里是一种构造这样的PrincipalContext的方法。
Using myContext As New PrincipalContext ContextType.Domain, "dom.fr:389", "dc=dom,dc=fr", "jpb", "root.123");
之后,异常可以解释为userName
不是控制器上的有效samAccountName。