2011-09-05 73 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; 
    } 
相關問題