2011-09-07 16 views
9

Widzę pewne dziwne zachowanie tutaj przy użyciu PrincipalContext.ValidateCredentials. Konfiguracja składa się z dwóch domen Active Directory w konfiguracji nadrzędnej/podrzędnej (więc mamy domenę podstawową company.com i subdomeny development.company.com).ValidateCredentials zwraca wartość true dla nieznanego użytkownika?

Gdy sprawdzam dane uwierzytelniające w domenie podstawowej, ValidateCredentials zachowuje się zgodnie z oczekiwaniami, zwracając wartość true dla dobrych par użytkowników/przejść i fałsz dla czegokolwiek innego.

Jeśli jednak sprawdzę użytkownika w subdomenie, to dla poprawnej nazwy użytkownika/hasła ORAZ nieprawidłowych użytkowników zostanie zwrócona wartość ValidateCredentials. Jeśli podam prawidłowego użytkownika z nieprawidłowym hasłem, to poprawnie zwraca wartość false.

Teraz pracuję nad nim, wykonując najpierw UserPrincipal.FindByIdentity() i jeśli użytkownik istnieje, a następnie zadzwonię pod numer ValidateCredentials - ale chciałbym zrozumieć, co się dzieje.

Innym obejście szukałem na to przez przepuszczenie przez użytkownika jako domain\username jako MSDN entry for ValidateCredentials states:

W każdej wersji tej funkcji, łańcuch Nazwa użytkownika może być w jednym z wiele różnych formatów . Aby uzyskać pełną listę dopuszczalnych typów formatów , zobacz dokumentację ADS_NAME_TYPE_ENUM.

... z których wymieniona jest ta forma nazwy użytkownika. Ale to powoduje ValidateCredentials zawsze zwracają prawdę, bez względu na to, jaka kombinacja nazwy użytkownika i hasła mijam w

Stosowny kod jest:

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; 

każdego i wszystkich (jawne) sugestie mile widziane - Jestem. drapie mnie po głowie, ponieważ jest to sprzeczne z wszelkimi oczekiwaniami.

Muszę dodać: to działa jak ja na moim komputerze, które są członkami domeny podstawowej. Jednak próbowałem również uruchomić go w wierszu polecenia na moim komputerze jako użytkownik poddomeny (runas /user:subdomain\user cmd) z dokładnie takimi samymi wynikami.

+0

Mam dwie domeny. Mogę użyć adresu IP dla mojej domeny, aby wywoływać dane uwierzytelniające, i to się uda, jeśli po prostu podam nazwę użytkownika lub hasło dla użytkowników z którejkolwiek z tych domen. Jestem trochę zaskoczony, że nie muszę podawać tej dodatkowej informacji, i trochę pomylony, a następnie, w jaki sposób upewniam się, że sprawdzam właściwego użytkownika z właściwej domeny. (Czy nie byłoby możliwe, aby każdy z nich powiedział jalę?) – Greg

Odpowiedz

16

Pewna ilość googling później (nie, że byłem i wyjechałem z google cały dzień próbując znaleźć to mimo wszystko), mam found the answer.

Krótko mówiąc, jeśli konto gościa jest włączone w domenie, ValidateCredentials zwróci wartość PRAWDA nieznanemu użytkownikowi. Właśnie sprawdziłem stan użytkownika-gościa w development.company.com i na pewno wystarczy, że konto jest włączone. Jeśli konto gościa jest wyłączone, ValidateCredentials prawidłowo zwraca wartość false.

To jest dość fundamentalna kwestia, nie jestem pewien, czy jestem zainteresowany tym zachowaniem ... szkoda, że ​​nie jest to wyraźnie wspomniane w witrynie MSDN.

+0

Wow ... to łatwa miss, która mogłaby być dużą luką bezpieczeństwa. Dziękuję za odpowiedź! –

+2

Dlaczego AD API muszą być tak martwe? –

+0

Minęło 5 lat, a sprawa wciąż jest taka sama. Był zaskoczony, aby zobaczyć 'principalContext.ValidateCredentials (" bla "," bla ", ContextOptions.Negotiate)', aby zwrócić 'true'. – trailmax

0

Może to być związane z this:

The ValidateCredentials metoda wiąże się z serwerem określonym w konstruktorze . Jeśli parametry nazwa użytkownika i hasło są nieważne, poświadczenia podane w konstruktorze są sprawdzane. Jeśli w konstruktorze nie określono poświadczenia , a parametry hasła użytkownika i są puste, ta metoda sprawdza domyślne poświadczenia dla bieżącego użytkownika głównego.

+0

Nie ... jak się okazało, konto gościnne na poziomie domeny zostało włączone; jeśli go wyłączę, ValidateCrendentials robi to, co trzeba. (I jak to jest typowe, po większości dnia próbując znaleźć odpowiedź, 20 minut po zamieszczeniu tego, znajduję odpowiedź). –

+0

Tak zawsze sprawa :) – TheCodeKing

Powiązane problemy