Voglio convalidare una serie di credenziali rispetto al controller di dominio. per esempio:
Username: STACKOVERFLOW\joel
Password: splotchy
Metodo 1. Query Active Directory con rappresentazione
Molte persone suggeriscono di interrogare Active Directory per qualcosa. Se viene generata un'eccezione, allora sai che le credenziali non sono valide, come suggerito in questa domanda su stackoverflow .
Tuttavia, questo approccio presenta alcuni seri inconvenienti :
Non stai solo autenticando un account di dominio, ma stai anche eseguendo un controllo di autorizzazione implicito. Cioè, stai leggendo le proprietà dall'ANNUNCIO utilizzando un token di rappresentazione. Cosa succede se l'account altrimenti valido non ha il diritto di leggere dall'AD? Per impostazione predefinita, tutti gli utenti hanno accesso in lettura, ma i criteri di dominio possono essere impostati per disabilitare le autorizzazioni di accesso per account (e / o gruppi) limitati.
Il binding con AD ha un sovraccarico serio, la cache dello schema AD deve essere caricata sul client (cache ADSI nel provider ADSI utilizzato da DirectoryServices). Questa è sia rete che server AD, consuma risorse ed è troppo costosa per un'operazione semplice come l'autenticazione di un account utente.
Stai facendo affidamento su un errore di eccezione per un caso non eccezionale e presumendo che ciò significhi nome utente e password non validi. Altri problemi (ad es. Errore di rete, errore di connettività AD, errore di allocazione della memoria, ecc.) Vengono quindi interpretati erroneamente come errore di autenticazione.
Metodo 2. LogonUser Win32 API
Altri hanno suggerito di utilizzare la LogonUser()
funzione API. Sembra carino, ma sfortunatamente l'utente chiamante a volte ha bisogno di un'autorizzazione solitamente data solo al sistema operativo stesso:
Il processo che chiama LogonUser richiede il privilegio SE_TCB_NAME. Se il processo chiamante non dispone di questo privilegio, LogonUser non riesce e GetLastError restituisce ERROR_PRIVILEGE_NOT_HELD.
In alcuni casi, il processo che chiama LogonUser deve anche avere il privilegio SE_CHANGE_NOTIFY_NAME abilitato; in caso contrario, LogonUser non riesce e GetLastError restituisce ERROR_ACCESS_DENIED. Questo privilegio non è richiesto per l'account di sistema locale o per gli account membri del gruppo di amministratori. Per impostazione predefinita, SE_CHANGE_NOTIFY_NAME è abilitato per tutti gli utenti, ma alcuni amministratori potrebbero disabilitarlo per tutti.
Distribuire il privilegio " Agisci come parte del sistema operativo " non è qualcosa che vuoi fare volenti o nolenti - come Microsoft sottolinea in un articolo della knowledge base :
... il processo che chiama LogonUser deve avere il privilegio SE_TCB_NAME (in User Manager, questo è il diritto " Agisci come parte del sistema operativo "). Il privilegio SE_TCB_NAME è molto potente e non dovrebbe essere concesso a nessun utente arbitrario solo per poter eseguire un'applicazione che deve convalidare le credenziali.
Inoltre, una chiamata a LogonUser()
fallirà se viene specificata una password vuota.
Qual è il modo corretto per autenticare una serie di credenziali di dominio?
Mi capita di chiamare da codice gestito, ma questa è una domanda generale di Windows. Si può presumere che i clienti abbiano installato .NET Framework 2.0.