2011-09-05 58 views
3

我想查找用户所在的组列表。我尝试了几种解决方案,从 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是未处理”

+0

在您链接的文章中,有一个“获取用户组成员”部分...你试试看吗? –

+0

可以吗? st代码不适合你吗? – baalazamon

+0

顺便说一下,在这种情况下,true意味着该对象存在,而不是LDAP正在运行。也许你应该了解一些关于LDAP和Active Directory的基本知识。 –

回答

1

我在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; 
     } 
8

在.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在带来所需的类型。

+0

上的错误的foreach本着:“servern是不可操作”姓名:domaineName –

+0

也许你不具备所需的权限? –

+0

刚才问,系统工程师告诉 –

0

你确定上面的脚本是正确的并且能够正常运行?我不认为它会考虑嵌套组成员,所以我担心你可能没有获得用户所属的所有组的完整集合。

您知道,用户可以是X组的成员,而X组可以是Y组的成员,因此用户也可以是Y组的成员。

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

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

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

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

我希望它很容易,但它并不显得那么:-(

+0

这是您在很短的时间内第三次发布链接到该网站的链接。它是你的网站吗? –

0

使用此代码,而不是你的版本。这将给你的名单。这与原来的区别是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; 
    } 
相关问题