2011-01-13 9 views
7

Mam sytuacji gdzie używam następujący kod do weryfikacji członkostwa użytkownika w AD przed wykonaniem zadania w moim appWinform autoryzacja użytkownika za pomocą aktywnego katalogu

using System.Security.Principal; 
WindowsIdentity identity = WindowsIdentity.GetCurrent(); 
WindowsPrincipal principal = new WindowsPrincipal(identity); 
return principal.IsInRole("someGroup"); 

Powyższy kod działa poprawnie na komputerach w mojej domenie, jednak mam kilka maszyn, które nie są w mojej domenie, na których mam zainstalowaną aplikację WINFORM. Jak mogę zweryfikować członkostwo użytkownika w AD?

Edytuj - czy istnieje sposób na monitowanie logowania do systemu Windows?

+0

Czy masz na myśli to, że użytkownik (i twoja maszyna), który uruchamia Twoją aplikację WinForm jest w innej niezaufanej domenie lub w ogóle nie jest w domenie? Co masz na myśli na temat logowania do systemu Windows? Możesz faktycznie napisać własne okno dialogowe, aby zachęcić użytkownika do wprowadzenia jego użytkownika domeny i hasła. Następnie używasz jego poświadczeń domeny, aby rozmawiać z Active Directory. –

+0

Prawidłowo. niektóre komputery nie znajdują się w domenie. Gdzie mogę znaleźć informacje o przekazywaniu referencji za pomocą niestandardowego okna logowania? Próbowałem, mogę uwierzytelnić, ale nie mogę uzyskać informacji o członkostwie. Postępowałem zgodnie z tym http://support.microsoft.com/kb/326340 –

+1

Każdy komentarz na temat mojej proponowanej odpowiedzi? Czy Ci to pasuje? –

Odpowiedz

7

Ponieważ komputer nie jest w ogóle przyłączony do domeny, nie możemy użyć WindowsIdentity lub WindowsPrincipal, a następnie sprawdzić jego metodę IsInRole(). Metoda IsInRole() działa tylko wtedy, gdy komputer jest dołączony do domeny i używa konta komputera domeny do wykonania S4USelf.

Nie można również użyć podejścia LogonUser, ponieważ komputer nie pozwala na utworzenie sesji logowania z niezaufanego lasu.

Myślę, że możemy tylko przesyłać zapytania bezpośrednio do Active Directory, aby uzyskać potrzebne informacje. Kod w opublikowanej witrynie Microsoft KB nie działa tak dobrze, o ile mogę to stwierdzić. Próbuje zapytać o atrybut memberOf. Informacje o grupie nie zawsze są dostępne z atrybutów memberOf.

Właśnie napisałem funkcję IsInRole() za pomocą AccountManagement. Chyba właśnie tego chcesz. Funkcja IsInRole() wywoła funkcję rekursywną IsInGroup(), aby znaleźć wszystkie grupy, do których należy użytkownik.

private bool IsInRole(string domain, string username, string password, string role) 
{ 
    using (var context = new PrincipalContext(ContextType.Domain, domain, username, password)) 
    { 
     GroupPrincipal group = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, role); 
     UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, username); 
     return IsInGroup(user, group); 
    } 
} 

private bool IsInGroup(Principal principal, GroupPrincipal group) 
{ 
    if (principal.IsMemberOf(group)) 
     return true; 

    foreach (var g in principal.GetGroups()) 
    { 
     if (IsInGroup(g, group)) 
      return true; 
    } 

    return false; 
} 

Aby użyć tej funkcji IsInRole(), należy podać nazwę domeny i dane uwierzytelniające domeny. Jeśli podana nazwa użytkownika i hasło są nieprawidłowe, otrzymasz wyjątek.

Potrzebujesz .NET 3.5 SP1 do korzystania z interfejsu API AccountManagement. Możesz również zwrócić uwagę na to hotfix. API AccountManagement ma pewne błędy, jeśli działa w niektórych środowiskach. Może być konieczne zastosowanie poprawki.

Powiązane problemy