【问题标题】:See if user is part of Active Directory group in C# + Asp.net查看用户是否属于 C# + Asp.net 中的 Active Directory 组
【发布时间】:2011-01-12 10:27:53
【问题描述】:

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

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

【问题讨论】:

    标签: c# asp.net active-directory .net-3.5 active-directory-group


    【解决方案1】:
    【解决方案2】:

    你可以试试下面的代码:

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

    【讨论】:

    • 与 BC 的回答一样,上述代码不会测试嵌套成员资格
    【解决方案3】:

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

    【讨论】:

    • 我在列出的代码中收到此错误:未知错误 (0x80005000) 说明:在执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。异常详细信息:System.Runtime.InteropServices.COMException:未知错误(0x80005000)导致它的行是:“var src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc);”关于问题可能是什么的任何建议?我从您的示例中按原样复制了该功能。
    • @Ben 您确定您使用的帐户有权查询 AD 吗?许多地方都禁用了匿名绑定
    • 我正在使用 .NET 4.0,我不得不将这一行,var pc = new PrincipalContext(ContextType.Domain); 更改为 var pc = new PrincipalContext(ContextType.Domain, "MyDomainHere"); 以消除异常。之后完美运行。
    • @NickCraver 你为什么不处理 PrincipalContext 和 UserPrincipal ?
    【解决方案4】:

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

    【讨论】:

    • 当我使用这段代码时,我在 .Any() 方法上遇到编译错误,说没有扩展方法。我需要添加任何其他使用或引用吗?
    • @Antoops - 您需要为 System.Linq 添加 using 语句
    • +1 用于展示如何使用 GetMembers(true),这正是我递归检查组成员所需要的!
    【解决方案5】:

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

    【讨论】:

    • 好答案。谢谢你。几个非常小的修复:将结果初始化为您想要返回的类型 - 即列表或数组。替换这一行: src.ToList().ForEach(sr => result.Add(sr.SamAccountName));用这个:result = src.Select(x => x.SamAccountName).ToList(); // ToArray 如果你愿意的话
    【解决方案6】:

    Brandon Johnson,喜欢它,我使用了你所拥有的,但做了以下更改:

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

    【讨论】:

      【解决方案7】:

      这取决于用户是否在 AD 组中。在 AD 中,组可以是安全组或通讯组。即使对于安全组,也取决于是否需要将“域用户”或“用户”等组包括在成员资格检查中。

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

      我没有使用 UserPrincipal.GetAuthorizedGroups() 的原因是它有很多问题,例如要求调用帐户在 WAAG 中并且要求在 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;
          }
      

      【讨论】:

      • 所有其他答案对我来说都是错误的,因为它们不考虑嵌套组。谢谢。
      【解决方案8】:

      最简单的解决方案

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

      【讨论】:

        【解决方案9】:

        如果您尝试确定已通过 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; }
            }
        

        【讨论】:

          【解决方案10】:

          这是我的 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);
              }
          

          【讨论】:

            【解决方案11】:

            这看起来简单多了:

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

            【讨论】:

              【解决方案12】:
              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);
              

              【讨论】:

                【解决方案13】:

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

                使用 System.DirectoryServices 公共静态布尔 IsMemberOfGroupsToCheck(字符串 DomainServer,字符串 LoginID,字符串 LoginPassword) { string UserDN = "CN=John.Doe-A,OU=管理账户,OU=用户目录,DC=ABC,DC=com" string ADGroupsDNToCheck = "CN=ADGroupTocheck,OU=管理组,OU=组目录,DC=ABC,DC=com"; 字节[] sid,parentSID; 布尔检查 = 假; DirectoryEntry parentEntry; DirectoryEntry basechildEntry; 字符串 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(basechildEntry.Properties["tokenGroups"] 中的对象 GroupSid) { sid = (byte[])GroupSid; if (ConvertToOctetString(sid,false,false) == octetSID) { 检查=真; 休息; } } basechildEntry.Dispose(); parentEntry.Dispose(); 退货支票; }

                【讨论】:

                  【解决方案14】:

                  如何检查用户是否在 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;
                          }
                  

                  【讨论】:

                    【解决方案15】:

                    这应该适用于 .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);
                    }
                    

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

                    • 仅查找用户,然后仅使用其名称检查用户是否是组的成员(不需要查找组或遍历用户/组)
                    • Disposes 对象(使用usings)

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2014-03-29
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-01-19
                      相关资源
                      最近更新 更多