2010-02-03 12 views

Odpowiedz

1

Można spróbować następujący kod:

public bool Check_If_Member_Of_AD_Group(string username, string grouptoCheck, string domain, string ADlogin, string ADpassword) 
{ 
    
    try { 
        
        string EntryString = null; 
        EntryString = "LDAP://" + domain; 
        
        DirectoryEntry myDE = default(DirectoryEntry); 
        
        grouptoCheck = grouptoCheck.ToLower(); 
        
        
        myDE = new DirectoryEntry(EntryString, ADlogin, ADpassword); 
        
        DirectorySearcher myDirectorySearcher = new DirectorySearcher(myDE); 
        
        myDirectorySearcher.Filter = "sAMAccountName=" + username; 
        
        myDirectorySearcher.PropertiesToLoad.Add("MemberOf"); 
        
        SearchResult myresult = myDirectorySearcher.FindOne(); 
        
        int NumberOfGroups = 0; 
        
        NumberOfGroups = myresult.Properties["memberOf"].Count - 1; 
        
        string tempString = null; 
        
        while ((NumberOfGroups >= 0)) { 
            
            tempString = myresult.Properties["MemberOf"].Item[NumberOfGroups]; 
            tempString = tempString.Substring(0, tempString.IndexOf(",", 0)); 
            
            tempString = tempString.Replace("CN=", ""); 
            
            tempString = tempString.ToLower(); 
            tempString = tempString.Trim(); 
            
            if ((grouptoCheck == tempString)) { 
                
                    
                return true; 
            } 
            
                
            NumberOfGroups = NumberOfGroups - 1; 
        } 
        
            
        return false; 
    } 
    catch (Exception ex) { 
        
        System.Diagnostics.Debugger.Break(); 
    } 
    //HttpContext.Current.Response.Write("Error: <br><br>" & ex.ToString) 
} 
+2

Podobnie jak w przypadku odpowiedzi BC powyższy kod nie będzie testował dla członkostwa zagnieżdżonego –

+0

Ten kod nie kompiluje się nawet w wersji 3.5 C#, jaka jest oferta? – Justin

38

z 3,5 i System.DirectoryServices.AccountManagement to nieco czystsze:

public List<string> GetGroupNames(string userName) 
{ 
    var pc = new PrincipalContext(ContextType.Domain); 
    var src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc); 
    var result = new List<string>(); 
    src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); 
    return result; 
} 
+0

otrzymuję ten błąd na kodzie wymienionych: Nieznany błąd (0x80005000) Opis: Wystąpił nieobsługiwany wyjątek podczas wykonywania bieżącego żądania sieci. Sprawdź ślad stosu, aby uzyskać więcej informacji o błędzie i skąd pochodzi w kodzie. Szczegóły wyjątku: System.Runtime.InteropServices.COMException: Nieznany błąd (0x80005000) Linia powoduje ona: "var src = UserPrincipal.FindByIdentity (PC, nazwę użytkownika) .GetGroups (PC);" Jakieś sugestie dotyczące problemu? Skopiowałem funkcję tak jak jest z twojego przykładu. – Ben

+1

@ Czy jesteś pewien, że konto, z którego korzystasz, ma uprawnienia do wysyłania zapytań do AD? Wiele miejsca mają anonimowy wiąże niepełnosprawnych –

+10

Używam .NET 4.0 i musiałem zmienić tę linię, 'var pc = new PrincipalContext (ContextType.Domain);' na 'var pc = new PrincipalContext (ContextType.Domain "MyDomainHere"); 'Aby pozbyć się wyjątku. Po tym działa idealnie. – Dan

19

rozwiązanie Nick Craver za nie działa dla mnie w .NET 4.0. Dostaję błąd dotyczący rozładowanego AppDomain. Zamiast tego użyłem tego (mamy tylko jedną domenę). To sprawdzi grupy grup, a także bezpośrednie członkostwo w grupie.

using System.DirectoryServices.AccountManagement; 
using System.Linq; 

... 

using (var ctx = new PrincipalContext(ContextType.Domain, yourDomain)) { 
    using (var grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, yourGroup)) { 
     bool isInRole = grp != null && 
      grp 
      .GetMembers(true) 
      .Any(m => m.SamAccountName == me.Identity.Name.Replace(yourDomain + "\\", "")); 
    } 
} 
+0

Podczas korzystania z tego kodu, otrzymuję błąd kompilacji na metodę .Any() informujące o braku metody rozszerzenia. Czy muszę dodać jakiekolwiek inne użycie lub odwołanie? – Antoops

+1

@Antoops - musisz dodać instrukcję użycia dla System.Linq –

+0

+1 za pokazanie, jak używać GetMembers (true), co było dokładnie tym, czego potrzebowałem, aby rekurencyjnie sprawdzić członków grupy! –

15

kod poniżej będzie działać w .NET 4.0

private static string[] GetGroupNames(string userName) 
{ 
    List<string> result = new List<string>(); 

    using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN")) 
    { 
     using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc)) 
     { 
      src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); 
     } 
    } 

    return result.ToArray(); 
} 
+1

Dobra odpowiedź. Dziękuję Ci. Kilka bardzo drobnych poprawek: initalize result do typu, który chcesz zwrócić - liście lub tablicy. zamień tę linię: src.ToList(). ForEach (sr => result.Add (sr.SamAccountName)); z tym: result = src.Select (x => x.SamAccountName) .ToList(); // ToArray, jeśli wolisz – Sam

1

Brandon Johnson, kochał ją, kiedyś, co trzeba było, ale się następujące zmiany:

private static string[] GetGroupNames(string domainName, string userName) 
{ 
    List<string> result = new List<string>(); 

    using (PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, domainName)) 
    { 
     using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(principalContext, userName).GetGroups(principalContext)) 
     { 
      src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); 
     } 
    } 

    return result.ToArray(); 
} 
4

to zależy o tym, co masz na myśli, jeśli użytkownik jest w grupie AD. W AD grupy mogą być grupą bezpieczeństwa lub grupą dystrybucji. Nawet w przypadku grup bezpieczeństwa zależy to od tego, czy grupy, takie jak "Użytkownicy domeny" czy "Użytkownicy", muszą być uwzględnione w kontroli członkostwa.

IsUserInSecurityGroup będzie sprawdzać tylko grupy bezpieczeństwa i będzie działać dla grup typu Grupy podstawowej, takich jak "Użytkownicy domeny" i "Użytkownicy", a nie grup dystrybucyjnych. Rozwiąże to również problem z zagnieżdżonymi grupami. IsUserInAllGroup również sprawdzi grupy dystrybucyjne, ale nie jestem pewien, czy napotkasz problemy z uprawnieniami. Jeśli nie, użyj konta usługa, która jest w Waag (See MSDN)

Powód nie używam UserPrincipal.GetAuthorizedGroups() dlatego, że ma wiele problemów, takich jak wymagające konto wzywającą być w Waag i wymaganie nie ma wpisu w sIDHistory (See David Thomas' comment)

public bool IsUserInSecurityGroup(string user, string group) 
    { 
     return IsUserInGroup(user, group, "tokenGroups"); 
    } 
    public bool IsUserInAllGroup(string user, string group) 
    { 
     return IsUserInGroup(user, group, "tokenGroupsGlobalAndUniversal"); 
    } 

    private bool IsUserInGroup(string user, string group, string groupType) 
    { 
     var userGroups = GetUserGroupIds(user, groupType); 
     var groupTokens = ParseDomainQualifiedName(group, "group"); 
     using (var groupContext = new PrincipalContext(ContextType.Domain, groupTokens[0])) 
     { 
      using (var identity = GroupPrincipal.FindByIdentity(groupContext, IdentityType.SamAccountName, groupTokens[1])) 
      { 
       if (identity == null) 
        return false; 

       return userGroups.Contains(identity.Sid); 
      } 
     } 
    } 
    private List<SecurityIdentifier> GetUserGroupIds(string user, string groupType) 
    { 
     var userTokens = ParseDomainQualifiedName(user, "user"); 
     using (var userContext = new PrincipalContext(ContextType.Domain, userTokens[0])) 
     { 
      using (var identity = UserPrincipal.FindByIdentity(userContext, IdentityType.SamAccountName, userTokens[1])) 
      { 
       if (identity == null) 
        return new List<SecurityIdentifier>(); 

       var userEntry = identity.GetUnderlyingObject() as DirectoryEntry; 
       userEntry.RefreshCache(new[] { groupType }); 
       return (from byte[] sid in userEntry.Properties[groupType] 
         select new SecurityIdentifier(sid, 0)).ToList(); 
      } 
     } 
    } 
    private static string[] ParseDomainQualifiedName(string name, string parameterName) 
    { 
     var groupTokens = name.Split(new[] {"\\"}, StringSplitOptions.RemoveEmptyEntries); 
     if (groupTokens.Length < 2) 
      throw new ArgumentException(Resources.Exception_NameNotDomainQualified + name, parameterName); 
     return groupTokens; 
    } 
+0

Wszystkie inne odpowiedzi są dla mnie złe, ponieważ nie zajmują się zagnieżdżonymi grupami. Dzięki. –

10

Najprostszym rozwiązaniem

PrincipalContext pc = new PrincipalContext((Environment.UserDomainName == Environment.MachineName ? ContextType.Machine : ContextType.Domain), Environment.UserDomainName); 

GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "{GroupName}"); 
UserPrincipal up = UserPrincipal.FindByIdentity(pc, Environment.UserName); 
up.IsMemberOf(gp); 
7

metoda ta może być przydatna, jeśli starasz się określić, czy system Windows uwierzytelniony bieżący użytkownik jest w szczególności rola.

public static bool CurrentUserIsInRole(string role) 
{ 
    try 
    { 
     return System.Web.HttpContext.Current.Request 
        .LogonUserIdentity 
        .Groups 
        .Any(x => x.Translate(typeof(NTAccount)).ToString() == role); 
     } 
     catch (Exception) { return false; } 
    } 
2

Oto moje 2 centy.

static void CheckUserGroup(string userName, string userGroup) 
    { 
     var wi = new WindowsIdentity(userName); 
     var wp = new WindowsPrincipal(wi); 

     bool inRole = wp.IsInRole(userGroup); 

     Console.WriteLine("User {0} {1} member of {2} AD group", userName, inRole ? "is" : "is not", userGroup); 
    } 
3

ta wydaje się o wiele prostsza:

public bool IsInRole(string groupname) 
{ 
    var myIdentity = WindowsIdentity.GetCurrent(); 
    if (myIdentity == null) return false; 

    var myPrincipal = new WindowsPrincipal(myIdentity); 
    var result = myPrincipal.IsInRole(groupname); 

    return result; 
} 
0
var context = new PrincipalContext(ContextType.Domain, {ADDomain}, {ADContainer}); 
var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, {AD_GROUP_NAME}); 
var user = UserPrincipal.FindByIdentity(context, {login}); 
bool result = user.IsMemberOf(group); 
0

Jeśli chcesz sprawdzić członkostwa grup użytkowników, w tym zagnieżdżonych grup, które są pośrednio związane z grupą macierzystą użytkownika można spróbować użyć " tokenGroups "właściwości jak poniżej:

 
Using System.DirectoryServices 

public static bool IsMemberOfGroupsToCheck(string DomainServer, string LoginID, string LoginPassword) 
     { 
      string UserDN = "CN=John.Doe-A,OU=Administration Accounts,OU=User Directory,DC=ABC,DC=com" 
      string ADGroupsDNToCheck = "CN=ADGroupTocheck,OU=Administration Groups,OU=Group Directory,DC=ABC,DC=com"; 

      byte[] sid, parentSID; 
      bool check = false; 
      DirectoryEntry parentEntry; 
      DirectoryEntry basechildEntry; 
      string octetSID; 

       basechildEntry = new DirectoryEntry("LDAP://" + DomainServer + "/" + UserDN, LoginID, LoginPassword); 
       basechildEntry.RefreshCache(new String[] { "tokenGroups" }); 

       parentEntry = new DirectoryEntry("LDAP://" + DomainServer + "/" + ADGroupsDNToCheck, LoginID, LoginPassword); 
       parentSID = (byte[])parentEntry.Properties["objectSID"].Value; 
       octetSID = ConvertToOctetString(parentSID, false, false); 

       foreach(Object GroupSid in basechildEntry.Properties["tokenGroups"]) 
       { 
        sid = (byte[])GroupSid; 
        if (ConvertToOctetString(sid,false,false) == octetSID) 
        { 
         check = true; 
         break; 
        } 
       } 

       basechildEntry.Dispose(); 
       parentEntry.Dispose(); 

       return check; 
     } 
Powiązane problemy