Udostępnij za pomocą


Debugowanie błędów uwierzytelniania systemu Windows

W przypadku korzystania z uwierzytelniania systemu Windows jako mechanizmu zabezpieczeń interfejs dostawcy obsługi zabezpieczeń (SSPI) obsługuje procesy zabezpieczeń. W przypadku wystąpienia błędów zabezpieczeń w warstwie SSPI są one udostępniane przez program Windows Communication Foundation (WCF). Ten temat zawiera strukturę i zestaw pytań, które ułatwiają diagnozowanie błędów.

Aby zapoznać się z omówieniem protokołu Kerberos, zobacz Kerberos Explained (Wyjaśnienie protokołu Kerberos). Aby zapoznać się z omówieniem interfejsu SSPI, zobacz SSPI.

W przypadku uwierzytelniania systemu Windows program WCF zwykle używa dostawcy zabezpieczeń Negotiate (SSP), który wykonuje wzajemne uwierzytelnianie Kerberos między klientem a usługą. Jeśli protokół Kerberos jest niedostępny, domyślnie program WCF powraca do nt LAN Manager (NTLM). Można jednak skonfigurować usługę WCF tak, aby używała tylko protokołu Kerberos (i zgłaszać wyjątek, jeśli protokół Kerberos jest niedostępny). Można również skonfigurować usługę WCF tak, aby korzystała z ograniczonych formularzy protokołu Kerberos.

Metodologia debugowania

Podstawowa metoda jest następująca:

  1. Ustal, czy używasz uwierzytelniania systemu Windows. Jeśli używasz innego schematu, ten temat nie ma zastosowania.

  2. Jeśli na pewno używasz uwierzytelniania systemu Windows, ustal, czy konfiguracja programu WCF korzysta z protokołu Kerberos direct czy Negotiate.

  3. Po ustaleniu, czy konfiguracja korzysta z protokołu Kerberos, czy NTLM, możesz zrozumieć komunikaty o błędach w poprawnym kontekście.

Dostępność protokołu Kerberos i NTLM

Dostawcy SSP protokołu Kerberos wymagają, aby kontroler domeny działał jako Centrum dystrybucji kluczy Protokołu Kerberos (KDC). Protokół Kerberos jest dostępny tylko wtedy, gdy zarówno klient, jak i usługa korzystają z tożsamości domeny. W innych kombinacjach kont protokół NTLM jest używany, jak podsumowano w poniższej tabeli.

W nagłówkach tabeli są wyświetlane możliwe typy kont używane przez serwer. W lewej kolumnie przedstawiono możliwe typy kont używane przez klienta.

Użytkownik lokalny System lokalny Użytkownik domeny Maszyna domeny
Użytkownik lokalny NTLM NTLM NTLM NTLM
System lokalny Anonimowy NTLM Anonimowy NTLM Anonimowy NTLM Anonimowy NTLM
Użytkownik domeny NTLM NTLM Kerberos Kerberos
Maszyna domeny NTLM NTLM Kerberos Kerberos

W szczególności cztery typy kont to:

  • Użytkownik lokalny: profil użytkownika tylko dla komputera. Na przykład: MachineName\Administrator lub MachineName\ProfileName.

  • System lokalny: wbudowany system konta na maszynie, która nie jest przyłączona do domeny.

  • Użytkownik domeny: konto użytkownika w domenie systemu Windows. Na przykład: DomainName\ProfileName.

  • Maszyna domeny: proces z tożsamością maszyny działający na maszynie podłączonej do domeny systemu Windows. Na przykład: MachineName\Network Service.

Uwaga / Notatka

Poświadczenie usługi jest przechwytywane, gdy wywołana zostanie metoda Open klasy ServiceHost. Poświadczenie klienta jest odczytywane za każdym razem, gdy klient wysyła komunikat.

Typowe problemy z uwierzytelnianiem systemu Windows

W tej sekcji omówiono niektóre typowe problemy z uwierzytelnianiem systemu Windows i możliwe środki zaradcze.

Protokół Kerberos

Problemy z protokołem Kerberos dotyczące SPN/UPN

W przypadku korzystania z uwierzytelniania systemu Windows, a protokół Kerberos jest używany lub negocjowany przez interfejs SSPI, adres URL używany przez punkt końcowy klienta musi zawierać w pełni kwalifikowaną nazwę domeny hosta usługi w adresie URL usługi. Przyjęto założenie, że konto, na którym jest uruchomiona usługa, ma dostęp do klucza głównej nazwy usługi (SPN) komputera utworzonego podczas dodawania komputera do domeny usługi Active Directory, co jest najczęściej wykonywane przez uruchomienie usługi na koncie usługi sieciowej. Jeśli usługa nie ma dostępu do klucza spN maszyny, musisz podać poprawną nazwę SPN lub nazwę główną użytkownika (UPN) konta, w ramach którego usługa jest uruchomiona w tożsamości punktu końcowego klienta. Aby uzyskać więcej informacji na temat działania usługi WCF z SPN i UPN, zobacz Tożsamość i uwierzytelnianie usługi.

W scenariuszach równoważenia obciążenia, takich jak farmy sieci Web lub ogrody sieci Web, typowym rozwiązaniem jest zdefiniowanie unikatowego konta dla każdej aplikacji, przypisanie nazwy SPN do tego konta i upewnienie się, że wszystkie usługi aplikacji działają na tym koncie.

Aby uzyskać nazwę SPN dla konta usługi, musisz być administratorem domeny usługi Active Directory. Aby uzyskać więcej informacji, zobacz Dodatek techniczny protokołu Kerberos dla systemu Windows.

Protokół Kerberos Direct wymaga, aby usługa działała na koncie komputerowym domeny

Dzieje się tak, gdy ClientCredentialType właściwość jest ustawiona na Windows , a NegotiateServiceCredential właściwość jest ustawiona na false, jak pokazano w poniższym kodzie.

WSHttpBinding b = new WSHttpBinding();
// By default, the WSHttpBinding uses Windows authentication
// and Message mode.
b.Security.Message.NegotiateServiceCredential = false;
Dim b As New WSHttpBinding()
' By default, the WSHttpBinding uses Windows authentication 
' and Message mode.
b.Security.Message.NegotiateServiceCredential = False

Aby rozwiązać ten problem, uruchom usługę przy użyciu konta komputera domenowego, takiego jak Network Service, na komputerze przyłączonym do domeny.

Delegowanie wymaga negocjacji poświadczeń

Aby używać protokołu uwierzytelniania Kerberos z delegowaniem, należy zaimplementować protokół Kerberos z negocjacją poświadczeń (czasami nazywaną jako Kerberos "wielostopniowy" lub "wieloetapowy"). W przypadku zaimplementowania uwierzytelniania Kerberos bez negocjowania poświadczeń (czasami nazywanego "jednym strzałem" lub "single-leg" Kerberos), pojawi się wyjątek.

Aby zaimplementować protokół Kerberos z negocjowaniem poświadczeń, wykonaj następujące czynności:

  1. Zaimplementuj delegację, ustawiając AllowedImpersonationLevel na Delegation.

  2. Wymuszaj negocjacje SSPI:

    1. Jeśli używasz powiązań standardowych, ustaw NegotiateServiceCredential właściwość na true.

    2. Jeśli używasz powiązań niestandardowych, ustaw AuthenticationMode atrybut elementu Security na SspiNegotiated.

  3. Wymagaj, aby negocjacja na interfejsie SSPI korzystała z protokołu Kerberos, nie zezwalając na użycie protokołu NTLM.

    1. Wykonaj to w kodzie z następującą instrukcją: ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. Możesz to zrobić w pliku konfiguracji, ustawiając allowNtlm atrybut na false. Ten atrybut jest zawarty w oknach<>.

Protokół NTLM

Negotiate SSP spada z powrotem do NTLM, ale NTLM jest wyłączony

Właściwość AllowNtlm jest ustawiona na false, co powoduje, że Windows Communication Foundation (WCF) podejmuje próbę zgłoszenia wyjątku, jeśli używany jest protokół NTLM. Ustawienie tej właściwości na false może nie uniemożliwiać wysyłania poświadczeń NTLM za pośrednictwem przewodu.

Poniżej pokazano, jak wyłączyć powrót do NTLM.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowNtlm = False

Logowanie NTLM kończy się niepowodzeniem

Poświadczenia klienta są nieprawidłowe dla usługi. Sprawdź, czy nazwa użytkownika i hasło są poprawnie ustawione i odpowiadają kontu znanemu komputerowi, na którym działa usługa. Protokół NTLM używa określonych poświadczeń do logowania się na komputerze usługi. Chociaż poświadczenia mogą być prawidłowe na komputerze, na którym jest uruchomiony klient, to logowanie zakończy się niepowodzeniem, jeśli poświadczenia nie są prawidłowe na komputerze usługi.

Występuje anonimowe logowanie NTLM, ale logowania anonimowe są domyślnie wyłączone

Podczas tworzenia klienta AllowedImpersonationLevel właściwość jest ustawiona na Anonymous, jak pokazano w poniższym przykładzie, ale domyślnie serwer nie zezwala na logowania anonimowe. Dzieje się tak, ponieważ domyślną wartością AllowAnonymousLogons właściwości WindowsServiceCredential klasy jest false.

Poniższy kod klienta próbuje włączyć logowania anonimowe (zwróć uwagę, że właściwość domyślna to Identification).

CalculatorClient cc =
    new CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Anonymous;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Anonymous

Poniższy kod usługi zmienia wartość domyślną, aby włączyć logowanie anonimowe przez serwer.

Uri httpUri = new Uri("http://localhost:8000/");
ServiceHost sh = new ServiceHost(typeof(Calculator), httpUri);
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = true;
Dim httpUri As New Uri("http://localhost:8000/")
Dim sh As New ServiceHost(GetType(Calculator), httpUri)
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = True

Aby uzyskać więcej informacji na temat personifikacji, zobacz Delegowanie i Personifikacja.

Alternatywnie klient jest uruchomiony jako usługa systemu Windows przy użyciu wbudowanego systemu kont SYSTEM.

Inne problemy

Poświadczenia klienta nie są poprawnie ustawione

Uwierzytelnianie systemu Windows używa wystąpienia zwróconego przez właściwość WindowsClientCredential klasy ClientCredentials, a nie ClientBase<TChannel> klasy. Poniżej przedstawiono niepoprawny przykład.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.UserName.UserName = GetUserName(); // wrong!
cc.ClientCredentials.UserName.Password = GetPassword(); // wrong!
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.UserName.UserName = GetUserName() ' wrong!
cc.ClientCredentials.UserName.Password = GetPassword() ' wrong!

Poniżej przedstawiono prawidłowy przykład.

CalculatorClient cc = new
    CalculatorClient("WSHttpBinding_ICalculator");
// This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName();
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword();
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
' This code returns the WindowsClientCredential type.            
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName()
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword()

SSPI jest niedostępne

Następujące systemy operacyjne nie obsługują uwierzytelniania systemu Windows w przypadku użycia jako serwera: Windows XP Home Edition, Windows XP Media Center Edition i Windows Vista Home edition.

Tworzenie i wdrażanie przy użyciu różnych tożsamości

Jeśli tworzysz aplikację na jednej maszynie i wdrażasz na innej maszynie i używasz różnych typów kont do uwierzytelniania na każdej maszynie, może wystąpić inne zachowanie. Załóżmy na przykład, że tworzysz aplikację na maszynie z systemem Windows XP Pro przy użyciu SSPI Negotiated trybu uwierzytelniania. Jeśli do uwierzytelniania używasz konta użytkownika lokalnego, zostanie użyty protokół NTLM. Po utworzeniu aplikacji należy wdrożyć usługę na maszynie z systemem Windows Server 2003, na której działa w ramach konta domeny. Na tym etapie klient nie będzie mógł uwierzytelnić usługi, ponieważ będzie on używał protokołu Kerberos i kontrolera domeny.

Zobacz także