查看用户是否是 C# 中 Active Directory 组的一部分 + ASP.net

发布于 2024-08-20 05:32:09 字数 108 浏览 11 评论 0原文

我需要一种方法来查看用户是否属于我的 .Net 3.5 asp.net c# 应用程序中的活动目录组。

我正在使用 msdn 上的标准 ldap 身份验证示例,但我真的不知道如何检查组。

I need a way to see if a user is part of an active directory group from my .Net 3.5 asp.net c# application.

I am using the standard ldap authentication example off of msdn but I don't really see how to check against a group.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

蝶…霜飞 2024-08-27 05:32:09

对于 3.5 和 System.DirectoryServices.AccountManagement 这是干净一点:

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

With 3.5 and System.DirectoryServices.AccountManagement this is a bit cleaner:

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;
}
嘿哥们儿 2024-08-27 05:32:09

Nick Craver 的解决方案在 .NET 4.0 中不适用于我。我收到有关已卸载 AppDomain 的错误。我没有使用它,而是使用了这个(我们只有一个域)。这将检查组的组以及直接组成员资格。

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

Nick Craver's solution doesn't work for me in .NET 4.0. I get an error about an unloaded AppDomain. Instead of using that, I used this (we only have one domain). This will check groups of groups as well as direct group membership.

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 + "\\", ""));
    }
}
疾风者 2024-08-27 05:32:09

下面的代码将在 .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();
}

The code below will work 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();
}
等风来 2024-08-27 05:32:09

最简单的解决方案

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

Simplest Solution

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);
嘿看小鸭子会跑 2024-08-27 05:32:09

如果您尝试确定经过 Windows 身份验证的当前用户是否处于特定角色,此方法可能会有所帮助。

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

This method might be helpful if you're trying to determine if the Windows authenticated current user is in a particular role.

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; }
    }
还给你自由 2024-08-27 05:32:09

这取决于您所说的用户是否位于 AD 组中是什么意思。在 AD 中,组可以是安全组或分发组。即使对于安全组,这也取决于是否需要将“域用户”或“用户”等组包含在成员资格检查中。

IsUserInSecurityGroup 将仅检查安全组,并且适用于主要组类型的组,例如“域用户”和“用户”,而不是通讯组。它还将解决嵌套组的问题。
IsUserInAllGroup 还将检查通讯组,但我不确定您是否会遇到权限问题。如果这样做,请使用 WAAG 中的服务帐户(请参阅 MSDN

。使用 UserPrincipal.GetAuthorizedGroups() 是因为它有很多问题,例如要求调用帐户位于 WAAG 中并要求 SidHistory 中没有条目 (请参阅 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;
    }

It depends on what you mean by if a user is in an AD group. In AD, groups can be a Security group or Distribution group. Even for security groups, it depends on if groups like "Domain Users" or "Users" need to be included in the membership check.

IsUserInSecurityGroup will only check for security groups and will work for Primary Group kind of groups like "Domain Users" and "Users", and not distribution groups. It will also solve the issue with nested groups.
IsUserInAllGroup will also check for Distribution groups, but I am not sure if you would run into permission issues. If you do, use a service account that is in WAAG (See MSDN)

The reason I am not using UserPrincipal.GetAuthorizedGroups() is because it has a lot of issues, such as requiring the calling account to be in WAAG and requiring there isn't an entry in 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;
    }
悲喜皆因你 2024-08-27 05:32:09

这是我的 2 美分。

    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);
    }

Here is my 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);
    }
请恋爱 2024-08-27 05:32:09

这看起来简单得多:

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

This seems much simpler:

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;
}
友欢 2024-08-27 05:32:09

您可以尝试以下代码:

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)
}

You could try the following code:

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)
}
絕版丫頭 2024-08-27 05:32:09

布兰登·约翰逊,喜欢它,我使用了你所拥有的,但做了以下更改:

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

Brandon Johnson, loved it, I used what you had, but made the following change:

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();
}
七月上 2024-08-27 05:32:09
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);
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);
萌能量女王 2024-08-27 05:32:09

如果您想检查用户组成员资格,包括间接链接到用户父组的嵌套组,您可以尝试使用“tokenGroups”属性,如下所示:

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

If you want to check the user groups membership including the nested groups which is indirectly linked to the user parent group you can try use the "tokenGroups" properties as below:

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;
        }
云醉月微眠 2024-08-27 05:32:09

如何检查用户是否在 AD 成员和特定 AD 组成员中

//This Reference and DLL must be attach in your project         
//using System.DirectoryServices.AccountManagement;        


         public bool IsAuthenticated(string username, string pwd)
        {

            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "xxx.com"))   // Your Domain Name
            {
                if (pc.ValidateCredentials(username, password))  //User and Password is OK for Active Directory 
                {
                    UserPrincipal user = UserPrincipal.FindByIdentity(pc, username);  //Get User Active Directory Information Details
                    if (user != null)
                    {

                        var groups = user.GetAuthorizationGroups();   // Get User Authorized Active Directory Groups
                        foreach (GroupPrincipal group in groups)
                        {
                            if (group.Name.Equals("SpecificActiveDirectoryGroupName"))  //Check if user specific group members
                            { 
                                return true;
                            }

                        }
                    }
                }
            }
            return false;
        }

How to check user is in AD member and specific AD group member

//This Reference and DLL must be attach in your project         
//using System.DirectoryServices.AccountManagement;        


         public bool IsAuthenticated(string username, string pwd)
        {

            using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "xxx.com"))   // Your Domain Name
            {
                if (pc.ValidateCredentials(username, password))  //User and Password is OK for Active Directory 
                {
                    UserPrincipal user = UserPrincipal.FindByIdentity(pc, username);  //Get User Active Directory Information Details
                    if (user != null)
                    {

                        var groups = user.GetAuthorizationGroups();   // Get User Authorized Active Directory Groups
                        foreach (GroupPrincipal group in groups)
                        {
                            if (group.Name.Equals("SpecificActiveDirectoryGroupName"))  //Check if user specific group members
                            { 
                                return true;
                            }

                        }
                    }
                }
            }
            return false;
        }
走野 2024-08-27 05:32:09

这应该在 .NET 3.5+ 中工作

// using System.DirectoryServices.AccountManagement;
public static bool IsUserMemberOfGroup(string username, string group)
{
    using (var ctx = new PrincipalContext(ContextType.Domain))
    using (var usr = UserPrincipal.FindByIdentity(ctx, username))
        return usr.IsMemberOf(ctx, IdentityType.Name, group);
}

这与这里的很多答案类似,但是:

  • 仅查找用户,然后仅使用其名称检查用户是否是组的成员(不需要查找组)或迭代用户/组)
  • Dispose 对象(使用 using

This should work in .NET 3.5+

// using System.DirectoryServices.AccountManagement;
public static bool IsUserMemberOfGroup(string username, string group)
{
    using (var ctx = new PrincipalContext(ContextType.Domain))
    using (var usr = UserPrincipal.FindByIdentity(ctx, username))
        return usr.IsMemberOf(ctx, IdentityType.Name, group);
}

This is similar to a lot of answers here, but this:

  • only finds the user, then checks if the user is a member of a group using just its name (doesn't need to find the Group or iterate over the users/groups)
  • Disposes the objects (using usings)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文