2014-11-17 2 views
3

Principal.IsMemberOf(GroupPrincipal) (MSDN)이 다음 테스트에서 Domain Computers 그룹에 대해 false negative를 반환하는 이유는 무엇입니까?Principal.IsMemberOf()가 일부 그룹에 대해 false negative를 반환하는 이유는 무엇입니까?

[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가 실패했습니다. 컴퓨터가 'Domain Computers'그룹의 구성원이 아닙니다.

컴퓨터가 실제로 'GetGroups()'메서드가 올바르게 반환 된 "Domain Computers"그룹의 구성원입니다. 실제로 컴퓨터를 그룹에 추가하려고하면 PrincipalExistsException이 발생합니다.

사용자 및 "도메인 사용자"그룹과 똑같은 동작을 재현 할 수 있습니다. 그룹이 주요 그룹이기 때문에 이것이 가능한가? 이것들이 "기본"그룹이기 때문에 그것입니까?

수정 사항 : 우리는 .NET 4.5.1을 사용하고 있습니다.

+0

어떤 버전의 .NET을 사용합니까? –

+0

4.5.1을 사용 중입니다. 나는 그 정보를 질문에 추가 할 것이다. 감사! – Josh

답변

4

이 문제는 항상 존재하는 것으로 보입니다.

동일한 문제로 발견 한 모든 질문에 답을 얻지 못했습니다. 나는 이것이 버그로 제기되었지만 .NET 3.5 이후로 존재했다는 것을 발견하지 못했습니다.

예를 들어 true (물론 내 저작 도메인의 정보로 변경됨)을 반환하려고했습니다. 아무리해도 false을 반환했습니다. dotPeek에서 Principal 클래스를 디 컴파일하면 추측 만 가능합니다. .NET Framework 코드로 들어가기 위해 Visual Studio를 설치하고 설정하는 것은 필요한 방법으로 들어 가지 않기 때문에 흉상이었습니다. 다른 .NET 프레임 워크 코드로 이동할 수 있지만 Principal에는 아무 것도 없습니다. 이 태그가 SecurityCriticalAttribute 태그가있는 메소드와 관련이 있는지 확실하지 않습니다. 그것에 대한 확인을 좋아할 것입니다.

내 의견은 버그로 신고하고 컴퓨터가 구성원인지 확인하기 위해 다른 경로로 이동하는 것이 좋습니다. 내 테스트에서 group.Members에는 컴퓨터가 포함되어있었습니다. - GroupPrincipal.IsMemberOf always returns false

A 2010 MSDN Blog entry with a comment that had the same issue as you.

주위

일 :

나는 여기

4.5.1 일부 참조입니다 .NET 3.5, 4.0, 4.5, 실행되는 동일한 문제가 발생 참고 : 일반적으로 이렇게 대답하지는 않지만이 문제와 관련된 모든 질문에 0 개의 대답 또는 해결 방법이 있으므로 미래의 독자들이이 문제에 대한 일종의 "대답"을 실제로 볼 수있게 도움이 될 것입니다.

+0

정보 주셔서 감사합니다. 내 연구는 당신이 발견 한 것과 거의 똑같은 결과를 낳았습니다. 나는 당신이했던 것과 동일한 기사/질문을 발견했고, 프레임 워크의 spelunking은 아무것도 발견하지 못했습니다. 참고로, 언급 한 블로그 기사는 .NET 3.5에만 적용됩니다. – Josh

+0

@Josh, yea이 기사는 다른 문제를 언급하고 있었지만이 기사에 대한 의견은 동일한 문제를 보여주었습니다. 그 이유는이 기사를 링크 한 이유입니다. 이 문제가 오래 전부터 있었음을 보여 주기만하면됩니다. – TyCobb

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. 
    } 
} 
0

그래서 여기에서했던 것과 동일한 문제가 발생할 수 있다고 생각합니다. 컴퓨터 계정과 사용자 계정이 아닙니다.

Principal.IsInRole("AD Group Name") always returns false, no exceptions thrown

코드를 실행하고 계정 컴퓨터가 오류를 일으키는 영역에서 모두 ComputersUsers 컨테이너 읽기 권한이 있는지 확인/문제가 발생하는 등록된다.