2010-03-29 13 views
18

Obecnie próbuję uwierzytelnić się za pośrednictwem usług Active Directory przy użyciu klasy PrincipalContext. Chciałbym, aby moja aplikacja była uwierzytelniana w domenie przy użyciu kontekstów Sealed i SSL. Aby to zrobić, muszę używać the following constructor of PrincipalContext (link to MSDN page):Usługi Active Directory: PrincipalContext - Jaka jest nazwa wyróżniająca obiektu "kontenerowego"?

public PrincipalContext(
    ContextType contextType, 
    string name, 
    string container, 
    ContextOptions options 
) 

szczególności Używam konstruktora jako tak:

PrincipalContext domainContext = new PrincipalContext(
    ContextType.Domain, 
    domain, 
    container, 
    ContextOptions.Sealing | ContextOptions.SecureSocketLayer); 

MSDN mówi o "pojemnik":

Kontener w sklepie używany jako źródło kontekstu. Wszystkie zapytania są wykonywane pod tym korzeniem, a wszystkie wstawki są wykonywane w tym pojemniku . W przypadku typów kontekstowych aplikacjiDirectory , parametr ten jest wyróżniającą się nazwą DN ( ) obiektu kontenera.

Co to jest DN obiektu kontenerowego? Jak mogę się dowiedzieć, jaki jest mój obiekt kontenera? Czy mogę zapytać o to serwer Active Directory (lub LDAP)?

Odpowiedz

28

Cóż, udało mi się dowiedzieć się problem:

PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain); 

domainContext.ValidateCredentials(userName, password, 
    ContextOptions.Negotiate | ContextOptions.SecureSocketLayer); 

Określając ContextOptions w metodzie ValidateCredentials (zamiast w konstruktorze), co pozwoliło mi uniknąć konieczności określić DN do pojemnika obiekt.

UPDATE:

Chociaż należy wyjaśnić, że po dalszych eksperymentów, stwierdziliśmy, że wszelkie pytania pochodzące z tego obiektu PrincipalContext odbywa ONZ szyfrowane.

Wygląda na to, że gdy ContextOptions są ustawione w ValidateCredentials, te opcje są używane tylko dla tego konkretnego wywołania ValidateCredentials. Ale tutaj jest, gdzie robi się dziwnie ...

Tak więc chciałem, aby moje zapytania do serwera AD zaszyfrowane również. Przykład zapytania:

UserPrincipal p = UserPrincipal.FindByIdentity(
    domainContext, IdentityType.SamAccountName, userName); 
var groups = p.GetGroups(); 
foreach (GroupPrincipal g in groups) { /* do something */ } 

Powyższy kod pobiera listę wszystkich grup, do których należy użytkownik, ale zdarza się w jasne (niezaszyfrowane). Po wielu próbach odkryłem, że DN nigdy nie musi być ustawiony.

PrincipalContext domainContext = new PrincipalContext(ContextType.Domain,domain, 
    null,ContextOptions.Negotiate | ContextOptions.SecureSocketLayer); 

Znalazłem, że mogę ustawić obiekt kontenera (DN) na wartość null. I to działa dobrze. Ustawienie go na pusty ciąg znaków ("") powoduje, że wyjątek stanowi nieznany typ, więc nie myśl, że możesz nadać mu pusty ciąg.

A oto część dziwna. Można by pomyśleć, że ustawienie opcji SecureSocketLayer w PrincipalContext oznaczałoby, że nie trzeba jawnie ustawić go podczas korzystania z VerifyCredentials. Ale odkryłem, że jeśli nie ustawiłem go w części VerifyCredentials, uwierzytelnianie zakończy się niepowodzeniem, ale zapytania (jak w przykładzie do grup) nadal będą szyfrowane.

Może po prostu nie w pełni rozumiem uwierzytelnianie i zapytania AD, ale wydaje mi się to dziwne zachowanie.

+1

Twoje wyjaśnienie "tej dziwnej strony" było kluczem do naprawienia 20-sekundowego opóźnienia wywoływania 'ValidateCredentials'. Dzięki! –

+0

Wiem, że to jest bardzo stare, ale badam, czy używać SSL zamiast podpisywania i natknąłem się na ten post. Wierzę, że możesz użyć 'null' w konstruktorze. Tak właśnie to robię, gdy chcę określić ContextOptions. Przykład: 'var pc = new PrincipalContext (ContextType.Domain, Environment.UserDomainName, null, ContextOptions.Sealing);' – famousKaneis

+0

@Name: Myślę, że to właśnie pokazuje kod w ostatnim bloku kodu. (FWIW, ledwie pamiętam o co chodzi, ale pamiętajcie, że byli naprawdę szczęśliwi, kiedy to rozgryzłem.) :) – Pretzel

Powiązane problemy