【问题标题】:Get all the groups the user belongs to获取用户所属的所有组
【发布时间】:2023-03-21 21:57:01
【问题描述】:

有两个域域 A 和域 B 之间相互信任(林级信任)。

'DomainA\BiggerGroup' 是域 A 中的一个用户组(域本地范围)。

'DomainB\SmallGroup' 是域 B 中的一个用户组(全局范围)。

DomainA\BigGroup 包含 DomainB\SmallGroup 作为子组。并且 DomainB\SmallGroup 包含 DomainB\User 作为成员。

查询:

作为 DomainB 的管理员,我们能否以编程方式列出 DomainB\User 所属的所有组?

WindowsIdentity.Groups 未枚举 DomainA\BiggerGroup。有什么方法可以列出用户所属的所有组(包括受信任域中的组)?

(WindowsIdentity 类具有“获取当前 Windows 用户所属的组”的 Group 属性。-http://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity(v=vs.110).aspx

【问题讨论】:

    标签: c# .net active-directory ldap directoryservices


    【解决方案1】:

    当您使用在它们之间具有林级信任的两个域时。我认为您可以使用 WindowsIdentity.Groups 再次尝试,但与全局目录 (GC) 目录建立连接(主体上下文),而不管其他任何 DC 目录。

    【讨论】:

      【解决方案2】:

      严格来说,一个用户在登录不同的域时可能有不同的组列表。 这是因为 domain-local 组仅限于组自己的域(顾名思义)。

      在你的情况下:

      • DomainB\User 登录 DomainA 时,组列表包含 DomainA\BiggerGroup 和 DomainB\SmallGroup
      • DomainB\User 登录 DomainB 时,组列表中包含 DomainB\SmallGroup

      一般来说,一个用户的组列表会包含:

      1. 来自 USER 域(在您的情况下为 DomainB)的全局和通用组,以及
      2. 来自连接域的域本地组
        (如果您在计算机上登录,则为 COMPUTER 域)
      3. 其他知名组,例如“Authenticated Users”、“Everyone”
        (如果您只对 AD 组感兴趣,可以忽略这一点)

      那么,w.r.t 你想从哪个域中找出 DomainB\User 的组列表?


      解决方案:

      要获得用户的准确组列表(无需提供该用户的密码),您可以使用 S4U Kerberos 扩展。 (请参阅下面链接中的 S4U2Self 部分)

      http://msdn.microsoft.com/en-us/magazine/cc188757.aspx

      链接建议使用WindowsIdentity。但是WindowsIdentity 解决方案有一个问题。

      // parameter must be in upn format
      WindowsIdentity identity = new WindowsIdentity("User@DomainB.com");
      

      问题是您无法控制从哪个域获取域本地组。
      例如在加入 DomainA 的计算机上,以 DomainB 中的用户身份登录,获取 DomainC 中用户的 WindowsIdentity。它将从域 A、B 或 C 获取域本地组?

      或者您可以使用链接中提到的LsaLogonUser Win32 函数。但它需要 14 个参数...
      我以前从未尝试过,无法对此发表评论。

      【讨论】:

      • 感谢您的调查。不幸的是,这并没有帮助,因为它仅列出了 DomainB 中的组:(
      • 这取决于谁在运行代码。如果当前用户来自DomainA,它将获得来自DomainA的DLG加上来自DomainB林的global+universal group。
      • 当前用户来自DomainB :(
      • 那么没有简单的方法。 ://
      【解决方案3】:

      您需要获取用户的令牌组。由于嵌套包括其他域,它将返回所有直接和间接的有效组成员资格。

          // this method will return all groups where the the user is a direct and indirect member of
          public static bool getTokenGroups(string domainFQDN, string alias, ref List<string> userGroups)
          {
              bool result = false;
      
              try
              {
                  SearchResult sr = default(SearchResult);
                  using (DirectoryEntry domainDE = new DirectoryEntry("LDAP://" + domainFQDN, "domain\\cn", "password", AuthenticationTypes.Secure))
                  {
                      using (DirectorySearcher searcher = new DirectorySearcher(domainDE))
                      {
                          searcher.Filter = String.Format("(&(objectClass=user)(sAMAccountName={0}))", alias);
                          sr = searcher.FindOne();
      
                          if (sr != null)
                          {
      
                              using (DirectoryEntry user = sr.GetDirectoryEntry())
                              {
                                  user.RefreshCache(new string[] { "tokenGroups" });
      
                                  for (int i = 0; i < user.Properties["tokenGroups"].Count; i++)
                                  {
                                      SecurityIdentifier sid = new SecurityIdentifier((byte[])user.Properties["tokenGroups"][i], 0);
                                      NTAccount nt = (NTAccount)sid.Translate(typeof(NTAccount));
                                      //do something with the SID or name (nt.Value)
                                      if(nt.Value.IndexOf('\\') > -1)
                                          userGroups.Add(nt.Value.Split('\\')[1]);
                                      else
                                          userGroups.Add(nt.Value);
                                  }
                              }
                          }
                      }
                  }
              }
              catch (Exception ex)
              {
                  EventLog.WriteEntry("source name", MethodBase.GetCurrentMethod().DeclaringType + "." + MethodBase.GetCurrentMethod().Name + "\r\n\r\nUnable to get user's token groups for domain: " + domainFQDN + " user: " + alias + "\r\n\r\n" + ex.Message, EventLogEntryType.Error);
              }
      
              return result;
          }
      

      【讨论】:

      • 感谢您的调查。不幸的是,这并没有帮助,因为它仅列出了 DomainB 中的组:(
      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-21
      • 2017-10-30
      • 2020-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多