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 à partir de mon .Net 3.5 asp.net application en c#.

j'utilise l'exemple standard d'authentification ldap hors msdn mais je ne vois pas vraiment comment vérifier contre un groupe.

45
demandé sur ekad 2010-02-03 03:50:52

13 réponses

avec 3.5 et système.DirectoryServices.Gestion de comptes 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
répondu Nick Craver 2011-05-31 12:46:13

la solution de Nick Craver ne fonctionne pas pour moi dans .NET 4.0. J'ai une erreur à propos d'une Appdomaine non chargée. Au lieu d'utiliser cela, j'ai utilisé ceci (nous n'avons qu'un seul domaine). Cela permettra de vérifier 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
répondu Dave Markle 2015-11-04 16:54:57

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
répondu Brandon Johnson 2011-12-08 14:09:34

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
répondu Adam 2013-03-20 22:44:15

cette méthode pourrait être utile si vous essayez de déterminer si L'utilisateur courant de Windows authentifié est dans 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
répondu p.campbell 2013-09-06 17:18:23

cela dépend de ce que vous entendez par si un utilisateur est dans un groupe publicitaire. Dans la publicité, 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 de si des groupes comme "utilisateurs du domaine" ou "utilisateurs" doivent être inclus dans la vérification de l'adhésion.

IsUserInSecurityGroup vérifiera uniquement les groupes de sécurité et travaillera pour le type de groupe principal de groupes comme "utilisateurs du domaine" et "utilisateurs", et non les groupes de distribution. Il permettra également de résoudre le problème avec imbriquée groupe. IsUserInAllGroup vérifiera également les groupes de Distribution, mais je ne suis pas sûr que vous rencontriez des problèmes de permission. 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 parce qu'il a beaucoup de problèmes, comme exiger que le compte appelant soit dans WAAG et qu'il n'y ait pas d'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;
    }
4
répondu Terry Tsay 2013-01-30 21:07:55

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
répondu Randy Gamage 2015-04-07 23:11:59

voilà 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);
    }
2
répondu Leonidius 2015-03-30 15:58:25

Brandon Johnson, adoré, j'ai utilisé ce que vous avez eu, mais apporté la modification suivante:

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
répondu Bill Daugherty 2013-09-06 16:56:29

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
répondu Mick Walker 2016-11-02 08:37:43
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
répondu Diego Deberdt 2016-09-14 13:54:46

si vous voulez vérifier l'appartenance aux groupes d'utilisateurs, y compris les groupes imbriqués qui sont indirectement liés au groupe parent utilisateur, vous pouvez essayer d'utiliser les propriétés "tokenGroups" comme suit:

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;
        }
0
répondu AsGoodAsLight 2016-09-21 04:39:46