获取用户所属的本地和域帐户组

3

我想要列出给定用户所属的所有组,同时支持本地机器账户和域账户。我可以使用以下代码获取域账户的组:

public void ListAllGroupsDomain()
{
    ListAllGroups(ContextType.Domain,
                  "myDomain",
                  "myDomainUser",
                  "myDomainPassword");
}

public void ListAllGroups(ContextType contextType
                          string name,
                          string username,
                          string password)
{
    using (var context = new PrincipalContext(contextType,
                                              name,
                                              username,
                                              password))
    {
        using (var findByIdentity = UserPrincipal.FindByIdentity(context, "testedit"))
        {
            if (findByIdentity != null)
            {
                var groups = findByIdentity.GetGroups(context);
                var results = groups.Select(g => g.Name).ToArray();
                Console.WriteLine("Listing {0} groups", results.Count());
                foreach (var name in results)
                {
                    Console.WriteLine("{0}", name);
                }
            }
        }
    }
}

然而,如果我尝试调用与本地计算机相关的帐户,则会出现COM异常,指示我的用户名或密码不正确(但它们是正确的):

public void ListAllGroupsMachine()
{
    ListAllGroups(ContextType.Machine,
                  "myMachine",
                  "myMachineUser",
                  "myMachinePassword");
}

我猜想我在使用FindByIdentity查找机器账户时存在错误。因此,我尝试了一种稍微不同的方法,它不使用FindByIdentity:

public void ListAllGroups2(ContextType contextType
                          string name,
                          string username,
                          string password)
{
    using (var context = new PrincipalContext(contextType,
                                              name,
                                              username,
                                              password))
    {
        using (var userContext = new UserPrincipal(context))
        {
            var results = userContext.GetGroups();
            Console.WriteLine("Listing {0} groups:", results.Count());
            foreach (var principal in results)
            {
                Console.WriteLine("{0}", principal.Name);
            }
        }
    }
}

这个版本没有引发任何异常,但调用GetGroups()也没有返回任何结果。我如何获得一个特定用户属于的组,可靠地适用于机器和域帐户?

1个回答

6

感谢我从https://dev59.com/71DTa4cB1Zd3GeqPIl5T#3681442获得的一些帮助,我找到了我的错误。我设置PrincipalContext不正确。我不需要提供域、用户名或密码,只需要提供ContextType即可。以下代码适用于本地机器帐户和域帐户:

public void ListAllGroupsDomain()
{
    ListAllGroups(ContextType.Domain, "myDomainUsername");
}

public void ListAllGroupsMachine()
{
    ListAllGroups(ContextType.Machine, "myMachineUsername");
}

public void ListAllGroups(ContextType contextType, string userName)
{
    using (var context = new PrincipalContext(contextType))
    {
        using (var findByIdentity = UserPrincipal.FindByIdentity(context, userName))
        {
            if (findByIdentity != null)
            {
                var groups = findByIdentity.GetGroups(context);
                var results = groups.Select(g => g.Name).ToArray();
                Console.WriteLine("Listing {0} groups", results.Count());
                foreach (var name in results)
                {
                    Console.WriteLine("{0}", name);
                }
            }
        }
    }
}

我需要确认的唯一一件事是,在将用户名传递给ListAllGroups之前,务必从中删除域名,因为提供给我的函数在某些情况下会在用户名前添加它。


这正是我目前正在寻找的,但我在使用 .FindByIdentity 和 .GetGroups 调用时遇到了非常慢的访问速度。你有没有遇到性能问题? - Spikeh
Spikeh,你认为什么样的速度才算慢?在我处理这个问题时,我尝试了几种不同的方法,有些几乎是瞬间完成的,而有些则需要10秒以上的时间。不过,这已经是很久以前的事情了,我无法提供更多的信息。 - Gillfish
FindByIdentity使用ContextType.Machine大约需要4秒钟,而GetGroups则需要大约6秒钟。虽然我没有加入域 - 我在Windows 8.1上通过IISExpress运行。我想是时候进行一些缓存了。 - Spikeh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接