【问题标题】:I have a SID of a user account, and I want the SIDs of the groups it belongs to我有一个用户帐户的 SID,我想要它所属组的 SID
【发布时间】:2010-03-22 19:44:45
【问题描述】:

这必须从远程机器上获取。以下查询不适用于 SID,但适用于组和帐户名称。

"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""

它返回的 Win32_Group 对象以字符串的形式出现,它们只有域和名称(尽管 Win32_Group 有 SID 属性)。

我有一种下沉的感觉,我不得不这样做:

  1. 通过查询 Win32_SID 将 SID 转换为帐户名;
  2. 执行上面的查询;
  3. 通过查询 Win32_Group 将每个生成的组名转换为 SID。

【问题讨论】:

    标签: c# wmi wql


    【解决方案1】:

    你可以使用System.DirectoryServices.AccountManagement命名空间类吗?

    using (var context = new PrincipalContext( ContextType.Domain ))
    {
        using (var user = UserPrincipal.FindByIdentity( context, accountName ))
        {
            var groups = user.GetAuthorizationGroups();
            ...iterate through groups and find SIDs for each one
        }
    }
    

    它应该与 ContextType.Machine 一起使用,但您需要指定机器名称并拥有适当的权限。

    using (var context = new PrincipalContext( ContextType.Machine,
                                               "MyComputer",
                                               userid,
                                               password ))
    {
       ...
    }
    

    有一个很好的 MSDN article(虽然有点长)关于使用新的 .NET 3.5 帐户管理命名空间。

    【讨论】:

    • 我也需要能够对本地用户和组执行此操作。
    • ContextType.Machine 应该在创建 PrincipalContext 时枚举由名称指定的机器本地的用户和组。
    • 我想,如果我使用正确的远程凭据从 mpr.dll 使用 WNetUseConnection() 连接到 \\MACHINENAME,即使我和远程计算机不是其中的一部分,我也应该能够获取信息同一个域,对吧?
    • 我相信 PrincipalContext 有一个构造函数,允许您指定连接时使用的凭据(id/password):msdn.microsoft.com/en-us/library/bb341016.aspx
    • 让它工作。现在我希望有一个 Principal.FindBySID() 方法。
    【解决方案2】:

    是的,但有些方法取决于拥有一个域。

    1. 请参阅page 了解如何转换 SID 使用 P/Invoke 和 Windows API 或使用 .NET 2.0+ 且没有 P/Invoke 的用户 ID。

      使用 System.Security.Principal;

      // 将用户 sid 转换为域名\name string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();

    2. 如果您有 AD 并且 那里的用户 ID 然后使用 the DirectorySearcher method 或帐户管理 API 来查找组。 否则使用中概述的方法 this文章获取本地 团体。

    3. 现在使用@tvanfosson 建议的 API 来迭代组并获取 SID。或按照以下信息进行操作。

    在 ASP.NET 应用程序中,如果用户通过 Windows 身份验证而不是 Forms 身份验证,则可以使用这样的代码访问组信息。在这个例子中,我留下了一个关于在那个环境中抛出的异常的有趣注释,但它可能适用于其他用户:

    public List<string> GetGroupsFromLogonUserIdentity()
    {
        List<string> groups = new List<string>();
        HttpRequest request = HttpContext.Current.Request;
    
        if (request.LogonUserIdentity.Groups != null)
        {
            foreach (IdentityReference group in request.LogonUserIdentity.Groups)
            {
                try
                {
                    groups.Add(group.Translate(typeof(NTAccount)).ToString());
                }
                catch (IdentityNotMappedException)
                {
                    // Swallow these exceptions without throwing an error. They are
                    // the result of dead objects in AD which are associated with
                    // user accounts. In this application users may have a group
                    // name associated with their AD profile which cannot be
                    // resolved in the Active Directory.
                }
            }
        }
    
        return groups;
    }
    

    LogonUserIdentity 基于WindowsIdentity 类。您可以修改我的代码示例以在非 Web 应用程序中使用 WindowsIdentity 和功能。遍历一个组后,您应该能够执行以下操作来获取 SecurityIdentifier:

    SecurityIdentifier secid = group as SecurityIdentifier;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 2010-09-20
      相关资源
      最近更新 更多