2011-09-07 2 views
9

Sto vedendo alcuni comportamenti strani qui usando PrincipalContext.ValidateCredentials. Il set-up è costituito da due domini di Active Directory nell'impostazione padre/figlio (quindi abbiamo il dominio principale company.com e il sottodominio development.company.com).ValidateCredentials restituisce true per utente sconosciuto?

Quando convalido le credenziali rispetto al dominio principale, ValidateCredentials si comporta come previsto, restituendo true per coppie di utenti/passate e false per qualsiasi altra cosa.

Tuttavia, se convalido un utente nel sottodominio, ValidateCredentials restituisce true per entrambi i buoni nome utente/password E utenti non validi. Se fornisco un utente valido con una password non valida, restituisce correttamente false.

Ora ci sto lavorando intorno al momento facendo prima UserPrincipal.FindByIdentity() e se l'utente esiste, quindi chiamando ValidateCredentials - ma mi piacerebbe capire cosa sta succedendo.

Un'altra soluzione che ho guardato è passando attraverso il nome utente come domain\username come il MSDN entry for ValidateCredentials states:

In ogni versione di questa funzione, la stringa nome utente può essere in uno dei una varietà di formati diversi . Per un elenco completo dei tipi di formati accettabili , consulta la documentazione di ADS_NAME_TYPE_ENUM.

... di cui è elencata questa forma di nome utente. Ma questo fa sì che ValidateCredentials per tornare sempre vero, non importa quale combinazione di nome utente e password mi passa in

Il codice pertinente è:

bool authenticated = false; 

// Various options tried for ContextOptions, [etc] inc. explicit username/password to bind to AD with -- no luck. 
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain, null, ContextOptions.Negotiate, null, null)) 
{ 
    log(pc.ConnectedServer + " => " + pc.UserName + " => " + pc.Name + " => " + pc.Container); 
    using (var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, username)) 
    { 
     if (user != null) 
     { 
      log(user.DistinguishedName + "; " + user.DisplayName); 
      authenticated = pc.ValidateCredentials(username, password); 
     } else { 
      log("User not found"); 
      // Debug only -- is FindByIdentity() needed. This should always return 
      // false, but doesn't. 
      authenticated = pc.ValidateCredentials(username, password); 
     } 
    } 
} 
return authenticated; 

Qualsiasi e tutti (sensibile) suggerimenti di benvenuto - Sono. grattandomi la testa perché va contro ogni aspettativa.

Devo aggiungere: questo è in esecuzione come me sulla mia macchina, che sono entrambi membri del dominio principale. Tuttavia, ho anche provato a eseguirlo in un prompt dei comandi sulla mia macchina come utente del sottodominio (runas /user:subdomain\user cmd) con esattamente gli stessi risultati.

+0

Ho due domini. Posso usare l'indirizzo IP del mio dominio per chiamare le credenziali di convalida, e succede se ho appena passato il nome utente o la password per gli utenti di entrambi i domini. Sono un po 'sorpreso di non dover fornire questa informazione in più, e un po' confuso di come accerterei che sto convalidando l'utente giusto dal dominio giusto. (Non sarebbe possibile per ciascuno dire un jsmith?) – Greg

risposta

16

Una certa quantità di googling più tardi (non che io sono stato dentro e fuori di google tutto il giorno cercando di trovare questo in ogni caso), ho found the answer.

In parole semplici, se l'account Ospite è abilitato nel dominio, ValidateCredentials restituirà TRUE per un utente sconosciuto. Ho appena controllato lo stato dell'utente ospite in development.company.com e sono sicuro che l'account sia abilitato. Se ho l'account guest disabilitato, ValidateCredentials restituisce correttamente false.

Questo è un getcha abbastanza fondamentale, non sono sicuro che mi piace questo comportamento ... peccato non è esplicitamente menzionato su MSDN.

+0

Wow ... questa è una facile perdita che avrebbe potuto essere un grande buco di sicurezza. Grazie per la risposta! –

+2

Perché le API AD devono essere così cerebrali? –

+0

5 anni e il caso è sempre lo stesso. È stato sorpreso vedere 'principalContext.ValidateCredentials (" blah "," blah ", ContextOptions.Negotiate)' per restituire 'true'. – trailmax

0

Potrebbe essere collegato a this:

I ValidateCredentials metodo si lega al server specificato nel costruttore . Se i parametri nome utente e password sono nulli, le credenziali specificate nel costruttore sono convalidate. Se nel costruttore non sono state specificate credenziali e il nome utente e i parametri della password sono nulli, questo metodo convalida le credenziali di default per l'attuale numero.

+0

No ... come si è scoperto, l'account guest a livello di dominio era abilitato; se lo disattivo, ValidateCrendentials fa la cosa giusta. (E come è tipico, dopo la maggior parte del giorno cercando di trovare la risposta, 20 minuti dopo aver postato questo trovo la risposta). –

+0

Sì sempre il caso :) – TheCodeKing