Получить группы из Active Directory с помощью C # - PullRequest
7 голосов
/ 30 ноября 2010

У меня проблемы с получением групп из Active Directory через System.DirectoryServices

Первоначально я запустил свое приложение на компьютере, который был зарегистрирован в домене, но, поскольку это был действующий домен, я не хотел делать какие-либо записи в AD, поэтому я настроил компьютер с Windows XP в качестве хост-операционная система и установленный Windows Server 2003 на виртуальной машине.

Я добавил еще один порт Ethernet в машину и настроил коммутатор, 1 порт Ethernet выделен для виртуальной машины, а другой порт используется для хоста.

После настройки IP-адресов для их связи я перенес свое приложение на хост-компьютер и запустил его, но я получил DirectoryServicesCOMException.

С сообщением о том, что имя пользователя и пароль были недействительными :( просто чтобы проверить, что это не активный каталог, я создал третью виртуальную машину и установил Windows XP, которую я добавил в домен с учетными данными, проверенными в приложении, работает удовольствие.

Так что я подумал, что это должно быть потому, что машина, на которой запущено приложение, не является частью домена.

Вот блок кода, который вызывал проблему:

public CredentialValidation(String Domain, String Username, String Password, Boolean Secure)
{
     //Validate the Domain!
     try
     {
         PrincipalContext Context = new PrincipalContext(ContextType.Domain, Domain); //Throws Exception
         _IsValidDomain = true;

         //Test the user login
         _IsValidLogin = Context.ValidateCredentials(Username, Password);

         //Check the Group Admin is within this user
         //******HERE
         var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);

         foreach(Principal Result in Results)
         {
             if (Result.SamAccountName == "Domain Admins")
             {
                 _IsAdminGroup = true;
                 break;
             }
         }
         Results.Dispose();
         Context.Dispose();
     }
     catch (PrincipalServerDownException)
     {
         _IsValidDomain = false;
     }
 }

Информация в диалоге входа вводится так:

Domain: test.internal
Username: testaccount
Password: Password01

Надеюсь, что кто-то может пролить свет на эту ошибку.


Обновление:

После проверки журналов безопасности на сервере я вижу, что мои попытки входа в систему были успешными, но до:

_IsValidLogin = Context.ValidateCredentials(Username, Password);

Строка, после которой я проверяю группы, вызывает ошибку, поэтому основная проблема заключается в том, что строки кода ниже не работают правильно с компьютера, который не подключен к сети :

var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);

Ответы [ 2 ]

2 голосов
/ 30 ноября 2010

Раньше я занимался управлением пользователями через C # .NET.Я просто выкопал несколько методов, которые вы можете попробовать.

Следующие два метода получат объект DirectoryEntry для данного имени учетной записи SAM.Это берет DirectoryEntry, который является корнем OU, с которого вы хотите начать поиск учетной записи.

Другой даст вам список отличительных имен групп, членом которых является пользователь.Затем вы можете использовать эти DN для поиска в AD и получения объекта DirectoryEntry.

public List<string> GetMemberOf(DirectoryEntry de)
{
  List<string> memberof = new List<string>();

  foreach (object oMember in de.Properties["memberOf"])
  {
    memberof.Add(oMember.ToString());
  }

  return memberof;
}

public DirectoryEntry GetObjectBySAM(string sam, DirectoryEntry root)
{
  using (DirectorySearcher searcher = new DirectorySearcher(root, string.Format("(sAMAccountName={0})", sam)))
  {
    SearchResult sr = searcher.FindOne();

    if (!(sr == null)) return sr.GetDirectoryEntry();
    else
      return null;
  }
}
2 голосов
/ 30 ноября 2010

Согласно вашему фрагменту кода, вы терпите неудачу при попытке создать PrincipalContext перед вызовом ValidateCredentials.На этом этапе поток, выполняющий ваш код, все еще работает под локальной идентификацией (если вы находитесь в веб-процессе) или под идентификацией, с которой вы подписались на своем компьютере (для процесса Windows).Ни один из них не будет существовать в домене test.internal.

Возможно, вы захотите попробовать перегрузку PrincipalContext, которая включает имя пользователя и пароль в конструкторе.Смотри http://msdn.microsoft.com/en-us/library/bb341016.aspx

...