【问题标题】:Active directory : get groups where a user is member活动目录:获取用户所属的组
【发布时间】:2011-09-05 07:56:40
【问题描述】:

我想找到用户所属的组列表。我尝试了几种解决方案 http://www.codeproject.com/KB/system/everythingInAD.aspx 但没有结果。

这段代码给了我一个“真”,表示 LDAP 正在运行:

public static bool Exists(string objectPath)
{
    bool found = false;
    if (DirectoryEntry.Exists("LDAP://" + objectPath))
        found = true;
    return found;
}

谢谢,

更新 1:

public ArrayList Groups(string userDn, bool recursive)
{
    ArrayList groupMemberships = new ArrayList();
    return AttributeValuesMultiString("memberOf", "LDAP-Server",
        groupMemberships, recursive);
}

public ArrayList AttributeValuesMultiString(string attributeName,
string objectDn, ArrayList valuesCollection, bool recursive)
{
    DirectoryEntry ent = new DirectoryEntry(objectDn);
    PropertyValueCollection ValueCollection = ent.Properties[attributeName];
    IEnumerator en = ValueCollection.GetEnumerator();

    while (en.MoveNext())
    {
        if (en.Current != null)
        {
            if (!valuesCollection.Contains(en.Current.ToString()))
            {
                valuesCollection.Add(en.Current.ToString());
                if (recursive)
                {
                    AttributeValuesMultiString(attributeName, "LDAP://" +
                    en.Current.ToString(), valuesCollection, true);
                }
            }
        }
    }
    ent.Close();
    ent.Dispose();
    return valuesCollection;
}

我有一个例外:

PropertyValueCollection ValueCollection = ent.Properties[attributeName];

“COMException 未处理”

【问题讨论】:

  • 在您链接的文章中,有一个“获取用户组成员资格”部分...您尝试过吗?
  • 你能发布不适合你的代码吗?
  • 顺便说一句,在这种情况下,true 意味着对象存在,而不是 LDAP 正在运行。也许您应该了解一些有关 LDAP 和 Active Directory 的基本知识。
  • 你会在这里找到另一个post with the same question的链接。

标签: c# active-directory


【解决方案1】:

在 .NET 4 中,您可以通过以下方式使用新的 UserPrincipal 类非常轻松地做到这一点:

using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
    UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "your_login");
    foreach (var group in user.GetGroups())
    {
        Console.WriteLine(group.Name);
    }
}

您必须添加对System.DirectoryServices.AccountManagement 的引用才能引入所需的类型。

【讨论】:

  • foreach 行上的错误:“服务器无法运行”名称:domaineName
  • 也许您没有所需的权限?
  • 刚问,系统工程师说“不需要特殊权限才能阅读”
  • 如果你尝试这个是否有效:UserPrincipal user = UserPrincipal.Current
  • 那么您的设置有问题。这可能解释了您在尝试检索“memberof”值时的初始错误。
【解决方案2】:

我在 stackoverflow 上找到了解决方案。 connectionString 格式是这样的:

LDAP://domain.subdomain.com:389/DC=domain,DC=subdomain,DC=com

代码:

  public IList<string> GetGroupsByUser(string ldapConnectionString, string username)
        {
            IList<string> groupList = new List<string>();

            var identity = WindowsIdentity.GetCurrent().User;
            var allDomains = Forest.GetCurrentForest().Domains.Cast<Domain>();

            var allSearcher = allDomains.Select(domain =>
            {
                var searcher = new DirectorySearcher(new DirectoryEntry(ldapConnectionString));

                // Apply some filter to focus on only some specfic objects
                searcher.Filter = String.Format("(&(&(objectCategory=person)(objectClass=user)(name=*{0}*)))", username);
                return searcher;
            });

            var directoryEntriesFound = allSearcher
                .SelectMany(searcher => searcher.FindAll()
                    .Cast<SearchResult>()
                    .Select(result => result.GetDirectoryEntry()));

            var memberOf = directoryEntriesFound.Select(entry =>
            {
                using (entry)
                {
                    return new
                    {
                        Name = entry.Name,
                        GroupName = ((object[])entry.Properties["MemberOf"].Value).Select(obj => obj.ToString())
                    };
                }
            });

            foreach (var item in memberOf)
                foreach (var groupName in item.GroupName)
                    groupList.Add(groupName);

            return groupList;
        }

【讨论】:

    【解决方案3】:

    你确定上面的脚本是正确的并且可以正常工作吗?我认为它不会考虑嵌套组成员身份,因此我担心您可能无法获得用户所属的所有组的完整集合。

    您会看到,用户可能是 X 组的成员,而 X 组又可能是 Y 组的成员,因此用户也可能是 Y 组的成员。

    我认为上面引用的脚本可能无法扩展和枚举嵌套组成员资格。

    如果您有兴趣获得用户所属的全部成员资格,我也建议您考虑这个角度。

    我相信还有一些与确定组成员资格有关的其他问题。如果你有兴趣了解更多,这里有一个很好的讨论:

    http://www.activedirsec.org/t39703252/why-is-it-so-hard-to-enumerate-nested-group-memberships-in-a/

    我希望它更容易,但似乎并非如此:-(

    【讨论】:

    • 这是您在很短的时间内第三次发布指向该网站的链接。是你的网站吗?
    【解决方案4】:

    使用此代码而不是您的版本。这将为您提供列表。这个和原来的区别在于DirectorySearcher的用法。

        public ArrayList AttributeValuesMultiString(string attributeName,
             string objectDn, ArrayList valuesCollection, bool recursive)
        {
            using (DirectoryEntry ent = new DirectoryEntry(objectDn))
            {
                using (DirectorySearcher searcher = new DirectorySearcher(ent))
                {
                    searcher.PropertiesToLoad.Add(attributeName);
                    var result = searcher.FindOne();
                    ResultPropertyValueCollection ValueCollection = result.Properties[attributeName];
                    IEnumerator en = ValueCollection.GetEnumerator();
    
                    while (en.MoveNext())
                    {
                        if (en.Current != null)
                        {
                            if (!valuesCollection.Contains(en.Current.ToString()))
                            {
                                valuesCollection.Add(en.Current.ToString());
                                if (recursive)
                                {
                                    AttributeValuesMultiString(attributeName, "LDAP://" +
                                    en.Current.ToString(), valuesCollection, true);
                                }
                            }
                        }
                    }
                }
            }
            return valuesCollection;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多