2011-01-13 10 views
7

ho una situazione in cui sto utilizzando il seguente codice per verificare l'appartenenza dell'utente in AD prima di eseguire compiti nella mia appWinform autorizzazione utente tramite Active Directory

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

Il codice sopra funziona bene per le macchine sul mio dominio, tuttavia ho alcune macchine che non sono nel mio dominio su cui ho installato l'applicazione WINFORM. Come posso verificare l'appartenenza utente in AD?

Modifica: c'è un modo per richiedere l'accesso a Windows?

+0

Vuoi dire che l'utente (e la tua macchina) che esegue l'applicazione Winform si trova in un altro dominio non attendibile o non si trova in un dominio? Cosa intendi per l'accesso a Windows? È possibile scrivere la propria finestra di dialogo per richiedere all'utente di inserire il proprio dominio utente e password. Quindi, si utilizzano le sue credenziali di dominio per parlare con Active Directory. –

+0

corretto. alcune macchine non sono nel dominio. Dove posso trovare informazioni sul passaggio delle credenziali tramite una casella di accesso personalizzata? Ho provato, sono in grado di autenticarsi ma non ottenere informazioni sull'iscrizione. Ho seguito questo http://support.microsoft.com/kb/326340 –

+1

Qualche commento sulla mia risposta proposta? Per te funziona? –

risposta

7

Dato che il computer non è stato aggiunto al dominio, non è possibile utilizzare WindowsIdentity o WindowsPrincipal e quindi controllare il relativo metodo IsInRole(). Il metodo IsInRole() funziona solo se il tuo computer è collegato al dominio e sta utilizzando l'account del tuo computer di dominio per eseguire S4USelf.

Non è possibile utilizzare l'approccio LogonUser perché il computer non consente di creare una sessione di accesso da una foresta non sicura.

Penso che possiamo solo interrogare l'Active Directory direttamente per ottenere le informazioni che vogliamo. Il codice nel KB Microsoft pubblicato non funziona molto bene per quanto posso dire. Sta cercando di eseguire una query dall'attributo memberOf. Le informazioni sul gruppo non sono sempre disponibili dagli attributi memberOf.

Ho appena scritto una funzione IsInRole() utilizzando AccountManagement. Immagino che questo sia quello che vuoi. La funzione IsInRole() chiamerà una funzione ricorsiva IsInGroup() per scoprire tutti i gruppi a cui appartiene l'utente.

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; 
} 

Per utilizzare questa funzione IsInRole(), è necessario fornire il nome di dominio e le credenziali di dominio. Se il nome utente e la password forniti sono sbagliati, otterrai un'eccezione.

È necessario .NET 3.5 SP1 per utilizzare l'API di AccountManagement. Inoltre, potresti voler prestare attenzione a questo hotfix. L'API di AccountManagement ha alcuni bug se è in esecuzione in qualche ambiente. Potrebbe essere necessario applicare l'aggiornamento rapido.