为什么Principal.IsMemberOf(GroupPrincipal)
(MSDN)会在以下测试中为Domain Computers
组返回误报?
[TestMethod]
public void DomainComputerTest()
{
var distinguishedName = "CN=MyMachine,DC=SomeDomain,DC=local";
using( var pc = new PrincipalContext( ContextType.Domain, "SomeDomain.local", "UserName", "Password" ) )
using( var computer = ComputerPrincipal.FindByIdentity( pc, IdentityType.DistinguishedName, distinguishedName ) )
{
Assert.IsNotNull( computer );
// Get the groups for the computer.
var groups = computer.GetGroups().Cast<GroupPrincipal>();
foreach( var group in groups )
{
// Immediately turn around and test that the computer is a member of the groups it returned.
Assert.IsTrue( computer.IsMemberOf( group ), "Computer is not member of group {0}", group.Name );
}
}
}
结果消息:Assert.IsTrue失败。计算机不是“域名计算机”的成员。组
计算机确实是&#34; Domain Computers&#34;的成员。组,其中&#39; GetGroups()&#39;方法正确返回。实际上,如果您尝试将计算机添加到组中,则会抛出PrincipalExistsException。
我可以重现与用户和&#34;域用户&#34;完全相同的行为。组。这是因为这些团体是校长团体吗?是因为这些是&#34;默认&#34;组?
编辑添加:我们正在使用.NET 4.5.1。
答案 0 :(得分:7)
这似乎是一直存在的问题。
我在同一个问题上发现的每个问题都没有答案。我找不到任何说这是作为bug提交的内容,但似乎自.NET 3.5以来就存在。
我试图让你的例子返回true
(当然改变了我工作领域的信息)。无论如何,它返回false
。在dotPeek中反编译Principal
类仅得出推测。完成并设置Visual Studio以允许步入.NET框架代码是一个破坏,因为它不会进入必要的方法。我可以进入其他.NET框架代码,但Principal
上没有。不确定这是否与SecurityCriticalAttribute
标记的方法有关。我很乐意确认。
我的建议是将此文件作为错误提交,并在同一时间采用不同的路径来确定计算机是否为成员。在我的测试中,group.Members
确实包含了计算机。
我遇到了运行.NET 3.5,4.0,4.5,4.5.1
的相同问题以下是一些参考资料:
解决方法 - GroupPrincipal.IsMemberOf always returns false
A 2010 MSDN Blog entry with a comment that had the same issue as you.
注意:我通常不会这样回答,但因为我在这个问题上发现的每个问题都有0个答案或解决方法,我认为对未来的读者来说实际上看到某种形式是有益的。 &#34;回答&#34;关于这个问题。
答案 1 :(得分:1)
对于其他发现这一点的开发人员,这就是我最终要做的事情。这是我部署的代码的简化版本,但总的来说,我假设问题是主要组关系。 这可能不正确,但它现在对我们有效。
您可以像这样DirectoryEntry
获取ComputerPrincipal
个实例。
var entry = (DirectoryEntry)computerPrincipal.GetUnderlyingObject();
我正在使用此扩展方法来检查主要群组关系。
public static bool IsPrimaryGroupFor( this GroupPrincipal group, DirectoryEntry target )
{
// .Value will return an int like "123", which is the last part of the group's SID
var id = target.Properties[ "primaryGroupID" ].Value.ToString();
// strip the account domain SID from the group SID.
var groupId = group.Sid.Value.Remove( 0, group.Sid.AccountDomainSid.Value.Length + 1 );
// If the
return id.Equals( groupId, StringComparison.OrdinalIgnoreCase );
}
我们正在同步AD群组成员资格,因此我们在类似以下代码中发现了此问题;
public void AddComputerToGroups( ComputerPrincipal computer, ICollection<GroupPrincipal> groups )
{
var directoryEntry = (DirectoryEntry)computer.GetUnderlyingObject();
foreach( var principal in groups.Where(g=> !computer.IsMemberOf(g) )
{
principal.Members.Add( computer );
principal.Save(); // Exception thrown because computer already existed in the primary group.
}
}
答案 2 :(得分:0)
因此,我相信您可能遇到的问题与我在此处所遇到的问题相同,但对于计算机帐户而非用户帐户。
Principal.IsInRole("AD Group Name") always returns false, no exceptions thrown
验证执行代码的帐户是否具有对计算机所在域中的{strong> Computers
和Users
容器的读取权限导致错误/遇到问题的问题已登记。
答案 3 :(得分:0)
如果您要测试的组成员过多,也会发生这种情况。 IsMemberOf仅显示检查前1000个左右的条目。 要解决这种情况,请检查group.Members是否包含用户/计算机。