【问题标题】:Get group membership fast快速获得群组成员资格
【发布时间】:2009-04-04 11:57:26
【问题描述】:

我试图弄清楚当前的 windows 用户是本地管理员还是可以使用 UAC 来“获得”该组成员身份。

到目前为止,我的想法是这样的:

var adminIdentifier = new SecurityIdentifier("S-1-5-32-544");
var current = WindowsIdentity.GetCurrent();
bool isAdmin = current.Groups.Contains(adminIdentifier);
bool canBeAdmin = isAdmin;

if (!isAdmin)
{
    var adminGroupName = adminIdentifier.Translate(typeof(NTAccount)).Value;
    adminGroupName = adminGroupName.Substring(adminGroupName.LastIndexOf('\\'));
    string path = "WinNT://./" + adminGroupName + ",group";

    using (DirectoryEntry groupEntry = new DirectoryEntry(path))
    {
      foreach (object member in (IEnumerable)groupEntry.Invoke("Members"))
      {
        using (DirectoryEntry memberEntry = new DirectoryEntry(member))
        {
              object obVal = memberEntry.Properties["objectSid"].Value;
              SecurityIdentifier sid = null;
              if (null != obVal)
              {
                 sid = new SecurityIdentifier((Byte[])obVal,0);
              }

              canBeAdmin = Equals(current.User, sid);
              if (canBeAdmin)
                break;
        }
     }
   }
 }
 Console.WriteLine(canBeAdmin +" "+isAdmin);

此解决方案需要几毫秒的计算时间。比我之前尝试的基于 System.DirectoryServices.AccountManagement 的方法快得多。

不过,还有最后一件事让我感到困扰。我必须将管理组的 SecurityIdentifier 转换为名称。应该有办法得到 DirectoryEntry 直接使用 SID。根据谷歌的说法,这应该可行:

string path = "LDAP://<SID=" + adminIdentifier.ToString() + ">";

但是,这似乎不起作用。知道语法应该是什么样子吗?

【问题讨论】:

  • 在我给出另一个答案之前有几个问题... a) 您使用的是什么版本的 Windows?,b) 您能否确认 adminIdentifier.ToString() 的计算结果为“S-1-5 -32-544", c) 查询 LDAP 时是否遇到任何特定错误?
  • a) Windows Vista Ultimate。 b) 是的。 c) 错误表示找不到指定的域。我的计算机不在任何域中,因此这可能是一个线索。但是,我需要一个无论计算机是否在域中都能正常工作的解决方案。
  • 语法很好。我知道它有效,因为我也在使用它。我猜它不适用于 knownsids

标签: .net windows membership active-directory-group


【解决方案1】:

你试过WindowsPrincipal.IsInRole吗?

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
wp.IsInRole(new SecurityIdentifier("S-1-5-32-544"));
wp.IsInRole(WindowsBuiltInRole.Administrator);

【讨论】:

  • WindowsPrincipal.IsInRole() 在非提升模式下运行时为管理员组返回 false。这就是为什么我必须以另一种方式确定组成员身份。
【解决方案2】:

您是否尝试过在当前用户对应的 UserPrincipal 对象上使用GetAuthorizationGroups?如果 GetAuthorizationGroups 不包含机器本地组,您可能必须检查用户是否直接在本地管理员组中,或者本地管理员组是否包含用户所在的任何授权组。我没有在机器上下文中尝试过这个,所以我不确定如果它在使用时不使用域/全局/通用组计算本地组成员身份,是否还需要搜索域上下文以查找后一个匹配项机器上下文。

【讨论】:

  • GetAuthorizationGroups() 产生相同的结果,不幸的是性能相同(缺乏)。
【解决方案3】:

这应该是你想要的,除非我误解了:

var groupName = adminIdentifier.Translate(typeof(NTAccount)).Value;

【讨论】:

  • 我的问题陈述可能不够清楚 :-) 我有:一个 Windows 组的 SecurityIdentifier。我需要:该组的 DirectoryEntry 目前,我必须将 SID 转换为名称。我想摆脱这种转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 2016-05-09
  • 2022-01-03
  • 2021-07-26
  • 2016-12-26
相关资源
最近更新 更多