2012-03-15 7 views
6

Chcę sprawdzić zestaw danych uwierzytelniających w kontrolerze domeny. np .:Jak sprawdzić dane uwierzytelniające domeny (z natywnego kodu)?

Username: joel 
Password: splotchy 
Domain: STACKOVERFLOW 

W .NET 3.5 i nowszym you can use PrincipalContext.ValidateCredentials(username, password).

W przeciwnym razie masz kłopoty.

następstwie kodu w artykule How to validate user credentials on Microsoft operating systems Microsoft Knowledge Base, i dostać się do punktu, w którym nazywamy AcceptSecurityContext:

ss = AcceptSecurityContext(
     @pAS._hcred,   //[in]CredHandle structure 
     phContext,    //[in,out]CtxtHandle structure 
     @InBuffDesc,   //[in]SecBufferDesc structure 
     0,      //[in]context requirement flags 
     SECURITY_NATIVE_DREP, //[in]target data representation 
     @pAS._hctxt,   //[in,out]CtxtHandle strcture 
     @OutBuffDesc,   //[in,out]SecBufferDesc structure 
     ContextAttributes,  //[out]Context attribute flags 
     @Lifetime);   //[out]Timestamp struture 

wyjątkiem, że funkcja nie działa z:

SEC_E_NO_AUTHENTICATING_AUTHORITY (0x80090311)

Funkcja nieudana. Nie można skontaktować się z żadnym organem w celu uwierzytelnienia. Może to być spowodowane następującymi warunkami:

  • Nazwa domeny strony uwierzytelniającej jest niepoprawna.
  • Domena jest niedostępna.
  • Relacja zaufania nie powiodła się.

Byłoby to przydatne błąd, oprócz tego, że mogę potwierdzić tych samych danych z .NET 3.5 przy użyciu:

using (PrincipalContext context = new PrincipalContext(ContextType.Domain, domain)) 
{ 
    valid = context.ValidateCredentials(username, password);     
} 

Co może się zdarzyć, że pozwala .NET do sprawdzania poprawności zestawu poświadczeń , podczas gdy kod natywny nie może?


Aktualizacja: LogonUser zawiedzie również:

LogonUser("[email protected]", null, "splotchy", 
     LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_WINNT50, out token); 

z

1311 - There are currently no logon servers available to service the logon request 

Aktualizacja Dwa: Próbowałem zarówno preferowany Negotiate dostawcy, jak również jako th e Windows NT4 dziedzictwo „NTLM” usługodawca

String package = "Negotiate"; //"NTLM" 

QuerySecurityPackageInfo(package, [out] packageInfo); 
... 
AcquireCredentialsHandle(
     null,     //[in] principle 
     package,    //[in] package 
     SECPKG_CRED_OUTBOUND, //[in] credential use 
     null,     //[in] LogonID 
     pAuthIdentity,  //[in] authData 
     null,     //[in] GetKeyFn, not used and should be null 
     null,     //[in] GetKeyArgument, not used and should be null 
     credHandle,   //[out] CredHandle structure 
     expires);    //[out] expiration TimeStamp structure 
+0

Jak się nazywasz "InitializeSecurityContext"? (Który w szczególności SSP?) Jak konfigurujesz 'CredHandle'? –

+0

@EdwardThomson Próbowałem już preferowanego dostawcy 'Negotiate', a także' NTLM'. 'CredHandle' jest inicjowany poprzez wywołanie' AcquireCredentialsHandle'. –

+0

Wydaje mi się, że pamiętam, że miałem podobny problem, chociaż to było lata temu, a kwestia jest niewyraźna. Czy są jakieś zmiany, jeśli uruchomisz w/podwyższone uprawnienia? (Administrator domeny może?) –

Odpowiedz

0

Przypuszczam, że jest to, aby rozwiązać ten sam problem co innego question które pisał.

W pewnym sensie rozumiem, co próbujesz teraz zrobić. Pozwól, że podsumuję to, co napisałeś w innym poście.

Username Password Domain    Machine on domain? Validate as 
======== ======== ================= ================== ============== 
iboyd  pass1  .     No     Local account 
iboyd  pass1  (empty)   No     Local account 
iboyd  pass1  stackoverflow.com No     Domain account 
iboyd  pass1  .     Yes     Local account 
iboyd  pass1  (empty)   Yes     Domain account 
iboyd  pass1  stackoverflow.com Yes     Domain account 

Chcesz

  1. uwierzytelnić użytkownika z domeny, że urządzenie nie ufa
  2. uwierzytelnić użytkownika z domeny, że urządzenie zaufanego
  3. uwierzytelnić użytkownika lokalnego

Pierwsze dwa przypadki można osiągnąć, wykonując odpowiednie uzgadnianie protokołu SSPI z kontrolerem domeny . Artykuł KB, do którego odnosisz się w innym pytaniu, zatrzymuje pętlę z powrotem do SSPI. Nie zadziała w przypadku numer jeden, ponieważ komputer kliencki nie ma zaufania do domeny, do której uwierzytelniany jest użytkownik. To powinno być powodem, dla którego widzisz SEC_E_NO_AUTHENTICATING_AUTHORITY.

wyciąć go krótko, jeśli chcesz zrobić dokładnie to samo, co

PrincipalContext.ValidateCredentials(username, password); 

trzeba obsłużyć użytkownika lokalnego odmiennie od użytkownika domeny. W przypadku użytkownika domeny należy wywołać ldap_bind_s, aby powiązać kontroler domeny przy użyciu podanych poświadczeń. W przypadku użytkownika lokalnego musisz użyć ADsOpenObject, aby powiązać się z WinnT: // YourComputerName przy użyciu podanych poświadczeń. To właśnie robi PrincipalContext.ValidateCredentials z tego, co czytałem w Reflektorze.

Nie widzę żadnego równoważnego pojedynczego natywnego API robiącego to samo dla ciebie.