活动目录:获取用户所在的组

我想找到用户所在的组列表。 我从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未处理”

在.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的引用以引入所需的类型。

我在stackoverflow上找到了解决方案。 connectionString格式如下:

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

代码 :

  public IList GetGroupsByUser(string ldapConnectionString, string username) { IList groupList = new List(); var identity = WindowsIdentity.GetCurrent().User; var allDomains = Forest.GetCurrentForest().Domains.Cast(); 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() .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; } 

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

您看,用户可以是X组的成员,而X组又可以成为Y组的成员,因此用户也将成为Y组的成员。

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

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

我相信还有一些与确定团体成员身份有关的其他问题。 如果您有兴趣了解更多信息,请在此处进行讨论:

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

我希望它更容易,但似乎不是这样:-(

使用此代码而不是您的版本。 这会给你列表。 这与原始版本之间的区别在于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; }