web-dev-qa-db-fra.com

Voir si l'utilisateur fait partie du groupe Active Directory dans C # + Asp.net

J'ai besoin d'un moyen de voir si un utilisateur fait partie d'un groupe Active Directory de mon application .Net 3.5 asp.net c #.

J'utilise l'exemple d'authentification LDAP standard en dehors de MSDN, mais je ne vois pas vraiment comment vérifier un groupe.

45
mike_h

Avec 3.5 et System.DirectoryServices.AccountManagement c'est un peu plus propre:

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;
}
38
Nick Craver

La solution de Nick Craver ne fonctionne pas pour moi dans .NET 4.0. Je reçois une erreur à propos d'un AppDomain non chargé. Au lieu d’utiliser cela, j’ai utilisé ceci (nous n’avons qu’un domaine). Ceci vérifiera les groupes de groupes ainsi que l’appartenance directe au groupe.

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 + "\\", ""));
    }
}
19
Dave Markle

Le code ci-dessous fonctionnera dans .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();
}
15
Brandon Johnson

Solution la plus simple

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);
10
Adam

Cette méthode peut s'avérer utile si vous essayez de déterminer si l'utilisateur actuel authentifié Windows a un rôle particulier.

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; }
    }
7
p.campbell

Cela dépend de ce que vous entendez par si un utilisateur est dans un groupe AD. Dans AD, les groupes peuvent être un groupe de sécurité ou un groupe de distribution. Même pour les groupes de sécurité, cela dépend si des groupes tels que "Utilisateurs du domaine" ou "Utilisateurs" doivent être inclus dans la vérification de l'appartenance.

IsUserInSecurityGroup recherchera uniquement les groupes de sécurité et fonctionnera pour les types de groupes du groupe principal tels que "Utilisateurs du domaine" et "Utilisateurs", et non les groupes de distribution. Cela résoudra également le problème des groupes imbriqués . IsUserInAllGroup recherchera également des groupes de distribution, mais je ne suis pas sûr que vous rencontriez des problèmes d'autorisation. Si vous le faites, utilisez un compte de service qui est dans WAAG ( Voir MSDN )

La raison pour laquelle je n'utilise pas UserPrincipal.GetAuthorizedGroups () est due à de nombreux problèmes, tels qu'exiger que le compte appelant soit dans WAAG et n'exiger aucune entrée dans SidHistory ( Voir le commentaire de David Thomas )

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;
    }
5
Terry Tsay

Cela semble beaucoup plus simple:

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;
}
3
Randy Gamage

Voici mes 2 cents.

    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
Leonidius
2
BC.

Brandon Johnson, j'ai adoré, j'ai utilisé ce que vous aviez, mais j'ai apporté le changement suivant:

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();
}
1
Bill Daugherty

Vous pouvez essayer le code suivant:

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)
}
1
Mick Walker

Si vous souhaitez vérifier l'appartenance aux groupes d'utilisateurs, y compris les groupes imbriqués indirectement liés au groupe d'utilisateurs, vous pouvez utiliser les propriétés "tokenGroups" comme ci-dessous:

 Utilisation de System.DirectoryServices 

 public bool statique IsMemberOfGroupsToCheck (chaîne DomainServer, chaîne ID de connexion, chaîne LoginPassword) 
 {
 string UserDN = "CN = John.Doe-A, OU = comptes d'administration, OU = annuaire des utilisateurs, DC = ABC, DC = com" 
 string ADGroupsDNToCheck = "CN = ADGroupTocheck, OU = Groupes d'administration, OU = Répertoire de groupes, 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"]. Valeur; 
 octetSID = ConvertToOctetString (parentSID, false, false); 

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

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

 retour chèque; 
 } 
0
AsGoodAsLight
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
Captain Sensible