Поделиться через


Отладка ошибок проверки подлинности Windows

При использовании проверки подлинности Windows в качестве механизма безопасности интерфейс поставщика поддержки безопасности (SSPI) обрабатывает процессы безопасности. При возникновении ошибок безопасности на уровне SSPI они отображаются Windows Communication Foundation (WCF). В этом разделе представлена платформа и набор вопросов для диагностики ошибок.

Общие сведения о протоколе Kerberos см. в статье Kerberos. Общие сведения об SSPI см. в статье SSPI.

Для проверки подлинности Windows WCF обычно использует поставщика поддержки безопасности Negotiate (SSP), который выполняет взаимную аутентификацию Kerberos между клиентом и службой. Если протокол Kerberos недоступен, по умолчанию WCF возвращается в NT LAN Manager (NTLM). Однако вы можете настроить WCF для использования только протокола Kerberos (и вызвать исключение, если Kerberos недоступен). Вы также можете настроить WCF для использования ограниченных форм протокола Kerberos.

Методология отладки

Базовый метод выглядит следующим образом:

  1. Определите, используется ли проверка подлинности Windows. Если вы используете любую другую схему, этот раздел не применяется.

  2. Если вы уверены, что используете аутентификацию Windows, определите, использует ли конфигурация WCF прямую аутентификацию Kerberos или согласование Kerberos.

  3. После определения того, используется ли конфигурация протокола Kerberos или NTLM, можно понять сообщения об ошибках в правильном контексте.

Доступность протокола Kerberos и NTLM

SSP Kerberos требует, чтобы контроллер домена действовал в качестве центра распространения ключей Kerberos (KDC). Протокол Kerberos доступен только в том случае, если клиент и служба используют идентификаторы домена. В других сочетаниях учетных записей используется NTLM, как описано в следующей таблице.

В заголовках таблицы отображаются возможные типы учетных записей, используемые сервером. В левом столбце показаны возможные типы учетных записей, используемые клиентом.

Местный пользователь Локальная система Пользователь домена Машина домена
Местный пользователь NTLM NTLM NTLM NTLM
Локальная система Анонимный NTLM Анонимный NTLM Анонимный NTLM Анонимный NTLM
Пользователь домена NTLM NTLM Kerberos Kerberos
Доменная машина NTLM NTLM Kerberos Kerberos

В частности, к четырем типам учетных записей относятся:

  • Локальный пользователь: профиль пользователя только для компьютера. Пример: MachineName\Administrator или MachineName\ProfileName.

  • Локальная система: встроенная система учетной записи на компьютере, который не присоединен к домену.

  • Пользователь домена: учетная запись пользователя в домене Windows. Например: DomainName\ProfileName.

  • Доменный компьютер: процесс с идентификацией машины, запущенный на машине, присоединенной к домену Windows. Например: MachineName\Network Service.

Замечание

Учетные данные службы фиксируются, когда вызывается метод Open класса ServiceHost. Учетные данные клиента считываются всякий раз, когда клиент отправляет сообщение.

Распространенные проблемы проверки подлинности Windows

В этом разделе рассматриваются некоторые распространенные проблемы проверки подлинности Windows и возможные средства защиты.

Протокол Kerberos

Проблемы с SPN/UPN в протоколе Kerberos

При использовании проверки подлинности Windows, когда протокол Kerberos используется или согласовывается с помощью SSPI, URL-адрес, которым пользуется конечная точка клиента, должен содержать полное доменное имя хоста службы в URL-адресе этой службы. Предполагается, что учетная запись, под которой запущена служба, имеет доступ к ключу основного имени службы (SPN), который создается при добавлении компьютера в домен Active Directory, что наиболее часто достигается путем запуска службы под учетной записью "Сетевой службы". Если у службы нет доступа к ключу имени принципала службы (SPN) компьютера, необходимо указать правильное имя принципала службы (SPN) или имя пользователя-принципала (UPN) учетной записи, под которой служба выполняется в идентичности конечной точки клиента. Дополнительные сведения о том, как WCF работает с SPN и UPN, см. в разделе Идентификатор службы и проверка подлинности.

В сценариях балансировки нагрузки, таких как веб-фермы или веб-сады, рекомендуется определить уникальную учетную запись для каждого приложения, назначить SPN этой учетной записи и убедиться, что все службы приложения работают под этой учетной записью.

Чтобы получить SPN для аккаунта службы, необходимо быть администратором домена Active Directory. Дополнительные сведения см. в техническом дополнение Kerberos для Windows.

Протокол Kerberos Direct требует запуска службы под учетной записью компьютера домена

Это происходит, когда свойству ClientCredentialType присваивается Windows, а свойству NegotiateServiceCredential присваивается false, как показано в следующем коде.

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

Чтобы устранить проблему, запустите службу с помощью учетной записи компьютера домена, например сетевой службы, на присоединенном к домену компьютере.

Для передачи полномочий требуется согласование учетных данных

Чтобы использовать протокол проверки подлинности Kerberos с делегированием, необходимо реализовать протокол Kerberos с согласованием учетных данных (иногда называется "многоэтапный" или "многошаговый" Kerberos). Если вы реализуете проверку подлинности Kerberos без согласования учетных данных (иногда называемую "one-shot" или "single-leg" Kerberos), будет выброшено исключение.

Чтобы реализовать Kerberos с согласованием учетных данных, сделайте следующее:

  1. Реализуйте делегирование, установив AllowedImpersonationLevel на Delegation.

  2. Требовать проведения согласования по SSPI:

    1. Если вы используете стандартные привязки, задайте свойству NegotiateServiceCredential значение true.

    2. Если вы используете пользовательские привязки, задайте атрибуту AuthenticationMode элемента Security значение SspiNegotiated.

  3. Требовать, чтобы согласование SSPI использовало Kerberos, не разрешая использовать NTLM:

    1. Выполните это в коде с помощью следующей инструкции: ChannelFactory.Credentials.Windows.AllowNtlm = false

    2. Кроме того, вы можете сделать это в файле конфигурации, задав для атрибута allowNtlm значение false. Этот атрибут содержится в <windows>.

Протокол NTLM

Согласование SSP возвращается к NTLM, но NTLM отключен

Для AllowNtlm свойства задано значение false, из-за чего Windows Communication Foundation (WCF) пытается с максимальными усилиями выдать исключение, если используется NTLM. Задание этого свойства false не может препятствовать отправке учетных данных NTLM по проводу.

Ниже показано, как отключить резервный возврат к NTLM.

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

Ошибка входа NTLM

Учетные данные клиента недействительны в службе. Убедитесь, что имя пользователя и пароль заданы правильно и соответствуют учетной записи, известной компьютеру, на котором выполняется служба. NTLM использует указанные учетные данные для входа на компьютер службы. Хотя учетные данные могут быть допустимыми на компьютере, на котором запущен клиент, вход не удастся, если учетные данные недопустимы на компьютере сервиса.

Анонимный вход в систему NTLM происходит, но анонимные входы в систему отключены по умолчанию.

При создании клиента свойству AllowedImpersonationLevel назначено значение Anonymous, как показано в следующем примере, но по умолчанию сервер запрещает анонимные входы. Это происходит из-за того, что значение AllowAnonymousLogons свойства WindowsServiceCredential класса по умолчанию равно false.

Следующий клиентский код пытается включить анонимный вход (обратите внимание, что свойство по умолчанию равно 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

Следующий код службы изменяет значение по умолчанию, чтобы включить анонимный вход на сервер.

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

Дополнительные сведения об олицетворении см. в разделе "Делегирование и олицетворение".

Кроме того, клиент работает в качестве службы Windows, используя встроенную систему учетной записи.

Другие проблемы

Учетные данные клиента не заданы правильно

Проверка подлинности Windows использует экземпляр WindowsClientCredential, который возвращается свойством ClientCredentials класса ClientBase<TChannel>, а не UserNamePasswordClientCredential. Ниже показан неверный пример.

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!

Ниже показан правильный пример.

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 недоступен

Следующие операционные системы не поддерживают проверку подлинности Windows при использовании в качестве сервера: Windows XP Home Edition, Windows XP Media Center Edition и Windows Vista Home Edition.

Разработка и развертывание с использованием различных удостоверений

Если вы разрабатываете приложение на одном компьютере и развертываете на другом компьютере и используете разные типы учетных записей для проверки подлинности на каждом компьютере, вы можете столкнуться с различным поведением. Например, предположим, что вы разрабатываете приложение на компьютере Windows XP Pro с помощью SSPI Negotiated режима проверки подлинности. Если для проверки подлинности используется локальная учетная запись пользователя, будет использоваться протокол NTLM. После разработки приложения вы развернете службу на компьютере Windows Server 2003, где он выполняется под учетной записью домена. На этом этапе клиент не сможет пройти проверку подлинности службы, так как он будет использовать Kerberos и контроллер домена.

См. также