2010-02-03 16 views

risposta

1

Si potrebbe provare il seguente codice:

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

Come per la risposta di BC, il codice precedente non testerà l'appartenenza nidificata –

+0

Questo codice non è nemmeno compilato in 3.5 C#, qual è l'accordo? – Justin

38

Con 3.5 e System.DirectoryServices.AccountManagement questo è un po 'più pulito:

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

Viene visualizzato questo errore nel codice elencato: Errore sconosciuto (0x80005000) Descrizione: si è verificata un'eccezione non gestita durante l'esecuzione della richiesta Web corrente. Si prega di rivedere la traccia dello stack per ulteriori informazioni sull'errore e sulla sua origine nel codice. Dettagli eccezione: System.Runtime.InteropServices.COMException: errore sconosciuto (0x80005000) La linea che causa è: "var src = UserPrincipal.FindByIdentity (pc, nome utente) .GetGroups (PC);" Qualche suggerimento su quale potrebbe essere il problema? Ho copiato la funzione così com'è dal tuo esempio. – Ben

+1

@ Sei sicuro che l'account che stai utilizzando disponga delle autorizzazioni per interrogare AD? Molti posti hanno legami anonimi disabilitati –

+10

Sto usando .NET 4.0 e ho dovuto modificare questa riga, 'var pc = new PrincipalContext (ContextType.Domain);' a 'var pc = new PrincipalContext (ContextType.Domain," MyDomainHere "); 'Per sbarazzarsi dell'eccezione. Dopo che funziona perfettamente. – Dan

19

soluzione di Nick Craver non funziona per me in .NET 4.0. Ottengo un errore su un AppDomain scaricato. Invece di usarlo, ho usato questo (abbiamo solo un dominio). Questo controllerà gruppi di gruppi e l'appartenenza diretta al gruppo.

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

Mentre utilizzo questo codice, ricevo errore di compilazione sul metodo .Any() che non dice alcun metodo di estensione. Devo aggiungere altro usando o riferimento? – Antoops

+1

@Antoops - è necessario aggiungere un'istruzione using per System.Linq –

+0

+1 per mostrare come utilizzare GetMembers (true), che era esattamente ciò di cui avevo bisogno per verificare in modo ricorsivo i membri del gruppo! –

15

Il codice di seguito funzionerà in .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

Buona risposta. Grazie. Un paio di correzioni minori: inizializza il risultato al tipo che vuoi restituire - cioè elenco o array. sostituire questa riga: src.ToList(). ForEach (sr => result.Add (sr.SamAccountName)); con questo: result = src.Select (x => x.SamAccountName) .ToList(); // ToArray se preferisci – Sam

1

Brandon Johnson, mi è piaciuto molto, ho usato quello che aveva, ma ha reso la seguente modifica:

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

Dipende su cosa intendi se un utente si trova in un gruppo di annunci. In AD, i gruppi possono essere un gruppo di sicurezza o un gruppo di distribuzione. Anche per i gruppi di sicurezza, dipende dal fatto che gruppi come "Domain Users" o "Users" devono essere inclusi nel controllo di appartenenza.

IsUserInSecurityGroup controllerà solo i gruppi di sicurezza e funzionerà per gruppi di gruppi principali come "Utenti dominio" e "Utenti" e non gruppi di distribuzione. Risolverà anche il problema con i gruppi nidificati. IsUserInAllGroup controlla anche i gruppi di distribuzione, ma non sono sicuro che si verifichino problemi di autorizzazione. In tal caso, utilizzare un account di servizio in WAAG (See MSDN)

La ragione per cui non sto utilizzando UserPrincipal.GetAuthorizedGroups() è perché ha un sacco di problemi, come richiedere l'account di chiamata per essere in WAAG e che richiede non v'è una voce nel 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

Tutte le altre risposte sono sbagliate per me perché non si prendono cura dei gruppi nidificati. Grazie. –

10

più semplice soluzione

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

Questo metodo potrebbe essere utile se si sta cercando di determinare se Windows autenticato utente corrente è in un particolare ruolo.

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

Ecco i miei 2 centesimi.

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

Questo sembra molto più semplice:

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

Se si desidera controllare l'appartenenza dei gruppi di utenti tra cui i gruppi nidificati che è indirettamente legata al gruppo genitore utente si può provare a utilizzare la " proprietà di tokenGroups come di seguito:

 
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; 
     } 
Problemi correlati