2014-09-02 6 views
0

Я занимаюсь разработкой интрасети, которая показывает конкретные ссылки только в том случае, если пользователь является членом определенных групп в Active Directory.Получить членов группы, вложенных в другую группу

Я использую этот код, чтобы эффективно проверить, является ли пользователь членом группы. Работает нормально, если группа содержит только пользователей, но она не работает, если в ней есть группа. Мне нужно, чтобы он работал, даже если конкретный пользователь во вложенной группе!

public bool isMember(string user, string group) 
{ 
    string value = ""; 
    bool isMember = false; 

    try 
    { 
     DirectoryEntry entry = new DirectoryEntry(domain); 
     DirectorySearcher mySearcher = new DirectorySearcher(entry); 
     mySearcher.Filter = "sAMAccountname=" + user; 

     SearchResult mySearchResult; 

     mySearchResult = mySearcher.FindOne(); 

     PropertyValueCollection prop = mySearchResult.GetDirectoryEntry().Properties["memberOf"]; 

     for (int i = 0; i < prop.Count; i++) 
     { 
      value = prop[i].ToString(); 

      string[] groups = value.Split(','); 
      foreach (string property in groups) 
      { 
       if (groups[1] == group) 
       { 
        isMember = true; 
        break; 
       } 
      } 
     } 
     entry.Close(); 
     return isMember; 
    } 
    catch (COMException) 
    { 
     return false; 
    } 
} 

Как это сделать?

EDIT:

Я нашел код, который позволяет мне найти пользователя, даже если вложенной группе. Проблема в том, что она работает только в том случае, если мое подразделение содержит ONE группу, не работает, если есть несколько ... как вы думаете, я могу немного ее отредактировать, чтобы заставить ее работать правильно?

public bool isMember(string user, string group) 
{ 
    bool found = false; 

    PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain"); 
    GroupPrincipal p = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, group); 
    UserPrincipal u = UserPrincipal.FindByIdentity(ctx, user); 

    found = p.GetMembers(true).Contains(u); 

    p.Dispose(); 
    u.Dispose(); 

    return found; 
} 

Получил этот код из ->here < -

ответ

0

Существует два способа сделать это.

  1. Рекурсивно проверить свойство memberOf для каждой найденной группы. Обратите внимание, что могут быть круговые ссылки, поэтому вам нужно будет отслеживать группы посещенных групп, чтобы избежать бесконечной рекурсии.

  2. Используйте правило LDAP_MATCHING_RULE_IN_CHAIN для поиска всех групп, к которым принадлежит пользователь, прямо или косвенно. Для этого вам нужно сначала получить DN пользователя, а затем искать группы, которые содержат это имя пользователя, как прямой или косвенный элемент. Фильтр выглядит примерно так:

    String.Format("(member:1.2.840.113556.1.4.1941:={0})", userDN) 
    

вариант IIRC 1, как правило, быстрее, но, конечно, нужно больше кода.

+0

Я хотел бы следовать вашему первому варианту, но я не знаю, как это сделать. Не могли бы вы мне немного помочь? Извините, я совершенно новичок в этом. – Sarah

+0

Постараюсь выкопать образец. Между тем, вы можете рассмотреть альтернативу с помощью WindowsTokenRoleProvider, с помощью которой вы можете использовать HttpContext.Current.User.IsInRole для проверки членства в группе: http://msdn.microsoft.com/en-us/library/system.web.security .windowstokenroleprovider (v = vs.110) .aspx – Joe

+0

Что вы думаете о коде в моем редактировании? @Joe – Sarah

Смежные вопросы