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:
Ustal, czy używasz uwierzytelniania systemu Windows. Jeśli używasz innego schematu, ten temat nie ma zastosowania.
Jeśli na pewno używasz uwierzytelniania systemu Windows, ustal, czy konfiguracja programu WCF korzysta z protokołu Kerberos direct czy Negotiate.
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
lubMachineName\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:
Zaimplementuj delegowanie, ustawiając wartość AllowedImpersonationLevelDelegation.
Wymagaj negocjacji SSPI:
Jeśli używasz powiązań standardowych, ustaw
NegotiateServiceCredential
właściwość natrue
.Jeśli używasz powiązań niestandardowych, ustaw
AuthenticationMode
atrybut elementuSecurity
naSspiNegotiated
.
Wymagaj negocjacji interfejsu SSPI, aby korzystać z protokołu Kerberos, nie zezwalając na korzystanie z protokołu NTLM:
Wykonaj to w kodzie z następującą instrukcją:
ChannelFactory.Credentials.Windows.AllowNtlm = false
Możesz to zrobić w pliku konfiguracji, ustawiając
allowNtlm
atrybut nafalse
. 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 false
wartość , 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.