Udostępnij za pośrednictwem


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 Omówienie protokołu Kerberos. Aby zapoznać się z omówieniem interfejsu SSPI, zobacz SSPI.

W przypadku uwierzytelniania systemu Windows program WCF zwykle używa dostawcy negocjacja obsługi zabezpieczeń (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 PROTOKÓŁ NTLM Anonimowy PROTOKÓŁ NTLM Anonimowy PROTOKÓŁ NTLM Anonimowy PROTOKÓŁ 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 uruchomioną na maszynie przyłączonej do domeny systemu Windows. Na przykład: MachineName\Network Service.

Uwaga

Poświadczenie usługi jest przechwytywane po wywołaniu OpenServiceHost metody klasy. 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 nazwą SPN/upN z protokołem Kerberos

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 sposobu działania usługi WCF z nazwą SPN i nazwą UPN, zobacz Service Identity and Authentication (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 w ramach konta komputera 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 maszyny domeny, takiego jak usługa sieciowa, na maszynie przyłączonej do domeny.

Delegowanie wymaga negocjacji poświadczeń

Aby używać protokołu uwierzytelniania Kerberos z delegowaniem, należy zaimplementować protokół Kerberos z negocjacji poświadczeń (czasami nazywanych "wielostopniowymi" lub "wieloetapowymi" Kerberos). W przypadku zaimplementowania uwierzytelniania Kerberos bez negocjacji poświadczeń (czasami nazywanych "jednym strzałem" lub "single-leg" Kerberos), zostanie zgłoszony wyjątek.

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

  1. Zaimplementuj delegowanie, ustawiając wartość AllowedImpersonationLevelDelegation.

  2. Wymagaj negocjacji 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 negocjacji interfejsu SSPI, aby korzystać z protokołu Kerberos, nie zezwalając na korzystanie z 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ść jest ustawiona AllowNtlm na falsewartość , co powoduje, że program Windows Communication Foundation (WCF) w celu wykonania najlepszego wysiłku w celu zgłoszenia wyjątku, jeśli jest używany protokół NTLM. Ustawienie tej właściwości na wartość może nie uniemożliwiać false 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 w usłudze. 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 WindowsClientCredential wystąpienia zwróconego ClientBase<TChannel> przez ClientCredentials właściwość klasy, a nie UserNamePasswordClientCredentialklasy . 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()

Interfejs SSPI jest niedostępny

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 też