2013-04-17 7 views
2

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

public void ListAllGroupsDomain() 
{ 
    ListAllGroups(ContextType.Domain, 
        "myDomain", 
        "myDomainUser", 
        "myDomainPassword"); 
} 

public void ListAllGroups(ContextType contextType 
          string name, 
          string username, 
          string password) 
{ 
    using (var context = new PrincipalContext(contextType, 
               name, 
               username, 
               password)) 
    { 
     using (var findByIdentity = UserPrincipal.FindByIdentity(context, "testedit")) 
     { 
      if (findByIdentity != null) 
      { 
       var groups = findByIdentity.GetGroups(context); 
       var results = groups.Select(g => g.Name).ToArray(); 
       Console.WriteLine("Listing {0} groups", results.Count()); 
       foreach (var name in results) 
       { 
        Console.WriteLine("{0}", name); 
       } 
      } 
     } 
    } 
} 

Однако, если я пытаюсь вызвать для учетной записи локального к машине, я получаю COM исключение о том, что мое имя пользователя или неверный пароль (который они не являются):

public void ListAllGroupsMachine() 
{ 
    ListAllGroups(ContextType.Machine, 
        "myMachine", 
        "myMachineUser", 
        "myMachinePassword"); 
} 

Я предполагаю, что я использую FindByIdentity неправильно для учетных записей. Так что я попытался немного другой подход, который не использует FindByIdentity:

public void ListAllGroups2(ContextType contextType 
          string name, 
          string username, 
          string password) 
{ 
    using (var context = new PrincipalContext(contextType, 
               name, 
               username, 
               password)) 
    { 
     using (var userContext = new UserPrincipal(context)) 
     { 
      var results = userContext.GetGroups(); 
      Console.WriteLine("Listing {0} groups:", results.Count()); 
      foreach (var principal in results) 
      { 
       Console.WriteLine("{0}", principal.Name); 
      } 
     } 
    } 
} 

Эта версия не бросать никаких исключений, но призыв к GetGroups() также не возвращает никаких результатов. Как я могу получить группы, к которым принадлежит определенный пользователь, который является надежным как для учетных записей машин, так и для домена?

ответ

3

Благодаря небольшой помощи, которую я почерпнул из https://stackoverflow.com/a/3681442/1222122, я понял, что я делаю неправильно. Я неправильно установил PrincipalContext. Мне не нужно было указывать домен, имя пользователя или пароль, просто ContextType. Следующий код работает как для локальных учетных записей машины и доменных учетных записей:

public void ListAllGroupsDomain() 
{ 
    ListAllGroups(ContextType.Domain, "myDomainUsername"); 
} 

public void ListAllGroupsMachine() 
{ 
    ListAllGroups(ContextType.Machine, "myMachineUsername"); 
} 

public void ListAllGroups(ContextType contextType, string userName) 
{ 
    using (var context = new PrincipalContext(contextType)) 
    { 
     using (var findByIdentity = UserPrincipal.FindByIdentity(context, userName)) 
     { 
      if (findByIdentity != null) 
      { 
       var groups = findByIdentity.GetGroups(context); 
       var results = groups.Select(g => g.Name).ToArray(); 
       Console.WriteLine("Listing {0} groups", results.Count()); 
       foreach (var name in results) 
       { 
        Console.WriteLine("{0}", name); 
       } 
      } 
     } 
    } 
} 

Единственных, что мне нужно обязательно сделать, чтобы вырезать домен из имени пользователя, прежде чем я передал его ListAllGroups, так как функция, которая была предоставляя его мне, в некоторых случаях добавьте его к имени пользователя.

+0

Это именно то, что я ищу для atm, но у меня очень медленный доступ к вызовам .FindByIdentity и .GetGroups. У вас возникли проблемы с производительностью? – Spikeh

+0

Как медленный для вас медленный, Спикех? Я пробовал несколько разных методов, когда я работал над этим, и, похоже, я помню, что некоторые из них были почти мгновенными, а некоторые - более 10 секунд. Это было так давно, что я не мог рассказать вам гораздо больше. – Gillfish

+0

FindByIdentity занимает около 4 секунд (с использованием ContextType.Machine) и GetGroups занимает около 6 секунд. Я не в домене, хотя - Windows 8.1, работающий через IISExpress. Время для кеширования, говорит. – Spikeh

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

  • Нет связанных вопросов^_^