Отладка ошибок проверки подлинности Windows
При использовании в качестве механизма обеспечения безопасности проверки подлинности Windows процессы безопасности обрабатываются интерфейсом поставщика поддержки безопасности SSPI. Если на уровне SSPI происходят ошибки безопасности, они регистрируются на уровне Windows Communication Foundation (WCF). В этом разделе описаны общие принципы и некоторые вопросы, помогающие диагностировать такие ошибки.
Общие сведения о протоколе Kerberos см. в статье Kerberos Explained (на английском языке); общие сведения об интерфейсе SSPI см. в разделе SSPI.
Для проверки подлинности Windows в WCF обычно используется поставщик SSP Negotiate, который выполняет взаимную проверку подлинности Kerberos между клиентом и службой. Если протокол Kerberos недоступен, по умолчанию в WCF используется протокол NT LAN Manager (NTLM). Однако можно настроить среду WCF таким образом, чтобы использовался только протокол Kerberos, а если он недоступен, создавалось исключение. Кроме того, можно настроить среду WCF на использование ограниченных форм протокола Kerberos.
Методология отладки
Базовый метод отладки состоит в следующем.
Определите, используется ли проверка подлинности Windows. Если используется какая-либо другая схема, этот раздел неприменим к такому сценарию.
Если используется проверка подлинности Windows, определите, используется ли в конфигурации WCF протокол Kerberos в явном виде, или же используется поставщик Negotiate.
После определения протокола, который используется в текущей конфигурации (Kerberos или NTLM), можно рассматривать сообщения об ошибках в правильном контексте.
Доступность протокола Kerberos и NTLM
Поставщику SSP Kerberos необходимо, чтоб контроллер домена выступал в роли центра распространения ключей Kerberos. Протокол Kerberos доступен только в том случае, если и клиент, и служба используют удостоверения домена. При других сочетаниях учетных записей используется протокол NTLM, что подтверждается следующей таблицей.
В заголовке таблицы приведены возможные типы учетных записей, используемые сервером. В левом столбце приведены возможные типы учетных записей, используемые клиентом.
Локальный пользователь | Локальная система | Пользователь домена | Компьютер домена | |
---|---|---|---|---|
Локальный пользователь |
NTLM |
NTLM |
NTLM |
NTLM |
Локальная система |
Anonymous NTLM |
Anonymous NTLM |
Anonymous NTLM |
Anonymous NTLM |
Пользователь домена |
NTLM |
NTLM |
Kerberos |
Kerberos |
Компьютер домена |
NTLM |
NTLM |
Kerberos |
Kerberos |
Здесь четыре типа учетных записей включают:
локальный пользователь: профиль пользователя, относящийся только к конкретному компьютеру. Пример: MachineName\Administrator или MachineName\ProfileName;
локальная система: встроенная учетная запись SYSTEM на входящем в состав домена компьютере;
пользователь домена: учетная запись пользователя в домене Windows. Пример: DomainName\ProfileName.
компьютер домена: процесс с удостоверением компьютера, выполняющийся на компьютере, который входит в состав домена Windows. Пример: MachineName\Network Service.
Примечание |
---|
Получение учетных данных службы происходит при вызове метода Open класса ServiceHost. Чтение учетных данных клиента происходит всякий раз, когда клиент отправляет сообщение. |
Распространенные проблемы проверки подлинности Windows
В этом разделе описаны некоторые распространенные проблемы проверки подлинности Windows и возможные решения.
Протокол Kerberos
Проблемы SPN/UPN, возникающие при использовании протокола Kerberos
Если при проверке подлинности Windows используется протокол Kerberos, или он выбирается с помощью интерфейса SSPI, URL-адрес, используемый конечной точкой клиента, должен включать полное доменное имя узла службы внутри URL-адреса службы. При этом подразумевается, что у учетной записи, от имени которой выполняется служба, есть доступ к ключу имени участника службы (SPN) компьютера (по умолчанию), который был создан при добавлении компьютера в домен Active Directory, что чаще всего осуществляется путем запуска службы от имени учетной записи Network Service. Если у службы нет доступа к ключу имени участника-службы компьютера, необходимо указать правильное имя участника службы или участника-пользователя (UPN) учетной записи, от имени которой служба выполняется в конечной точке клиента. Дополнительные сведения том, как WCF работает с именами участников-служб и участников-пользователей, см. в разделе Идентификация и проверка подлинности службы.
В сценариях с балансировкой нагрузки, например при использовании веб-ферм или веб-садов, распространена практика определения уникальной учетной записи для каждого из приложений, назначения этой учетной записи имени участника-службы и контроль за тем, чтобы все службы приложения выполнялись от имени этой учетной записи.
Чтобы получить для учетной записи службы имя участника-службы, нужны права администратора домена Active Directory. Дополнительные сведения см. в разделе Техническое дополнение Kerberos для Windows.
Для непосредственного применения протокола Kerberos необходимо, чтобы служба выполнялась от имени учетной записи компьютера домена
Такая ситуация возникает, когда свойство ClientCredentialType имеет значение Windows, а свойство NegotiateServiceCredential — false, как показано в следующем примере кода.
Dim b As New WSHttpBinding()
' By default, the WSHttpBinding uses Windows authentication
' and Message mode.
b.Security.Message.NegotiateServiceCredential = False
WSHttpBinding b = new WSHttpBinding();
// By default, the WSHttpBinding uses Windows authentication
// and Message mode.
b.Security.Message.NegotiateServiceCredential = false;
Чтобы решить эту проблему, запустите службу от имени учетной записи компьютера домена, например учетной записи Network Service, на компьютере, входящем в домен.
Для делегирования требуется согласование учетных данных
Для использования протокола проверки подлинности Kerberos с делегированием необходимо реализовать протокол Kerberos с согласованием учетных данных (иногда называется многоступенчатой проверкой подлинности Kerberos). Если проверка подлинности Kerberos реализована без согласования учетных данных (иногда называется одноступенчатой проверкой подлинности Kerberos), возникает исключение.
Чтобы реализовать протокол Kerberos с согласованием учетных данных, выполните следующие действия.
Реализуйте делегирование, присвоив свойству AllowedImpersonationLevel значение Delegation.
Потребуйте согласования SSPI:
если используются стандартные привязки, установите свойство
NegotiateServiceCredential
равным true;если используются пользовательские привязки, установите атрибут
AuthenticationMode
элементаSecurity
равным SspiNegotiated.
Потребуйте, чтобы при согласовании SSPI использовался протокол Kerberos, запретив использование NTLM:
для этого в коде воспользуйтесь инструкцией:
ChannelFactory.Credentials.Windows.AllowNtlm = false
;либо в файле конфигурации установите атрибут
allowNtlm
равным false. Этот атрибут содержится в элементе <windows> of <clientCredentials> element.
Протокол NTLM
В результате согласования SSP используется протокол NTLM, хотя протокол NTLM отключен
Свойство AllowNtlm имеет значение false, в результате чего Windows Communication Foundation (WCF) создает исключение, если используется протокол NTLM. Обратите внимание, что задание для данного свойства значения false не предотвращает отправку учетных данных NTLM по сети.
Ниже показано, как отключить переключение к протоколу NTLM.
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowNtlm = False
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;
Сбой входа NTLM
Учетные данные клиента недействительны на стороне службы. Проверьте, что имя пользователя и пароль заданы правильно и соответствуют учетной записи, которая известна компьютеру, на котором выполняется служба. Протокол NTLM использует указанные учетные данные для входа на компьютер службы. Хотя эти учетные данные могут быть недействительными на компьютере клиента, сбой входа произойдет, если они будут недействительными на компьютере службы.
Происходит анонимный вход NTLM, хотя по умолчанию анонимный вход отключен
При создании клиента свойство AllowedImpersonationLevel устанавливается равным Anonymous, как показано в следующем примере кода, но по умолчанию сервер запрещает анонимный вход. Это происходит потому, что свойство AllowAnonymousLogons класса WindowsServiceCredential по умолчанию имеет значение false.
Следующий код клиента пытается включить анонимный вход (обратите внимание, что по умолчанию свойство имеет значение Identification).
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Anonymous
CalculatorClient cc =
new CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Anonymous;
Следующий код службы изменяет значение по умолчанию, чтобы разрешить анонимный вход сервера.
Dim httpUri As New Uri("https://localhost:8000/")
Dim sh As New ServiceHost(GetType(Calculator), httpUri)
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = True
Uri httpUri = new Uri("https://localhost:8000/");
ServiceHost sh = new ServiceHost(typeof(Calculator), httpUri);
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = true;
Дополнительные сведения олицетворении см. в разделе Делегирование и олицетворение с использованием WCF.
Либо клиент может выполняться в качестве службы Windows от имени встроенной учетной записи SYSTEM.
Другие проблемы
Учетные данные клиента заданы неверно
При проверке подлинности Windows используется экземпляр WindowsClientCredential, возвращаемый свойством ClientCredentials класса ClientBase, а не экземпляр UserNamePasswordClientCredential. Ниже приведен пример с ошибкой.
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");
cc.ClientCredentials.UserName.UserName = GetUserName(); // wrong!
cc.ClientCredentials.UserName.Password = GetPassword(); // wrong!
Ниже приведен пример без ошибки.
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()
CalculatorClient cc = 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 Еdition.
Разработка и развертывание с использованием различных удостоверений
В случае разработки приложения на одном компьютере и его развертывания на другом компьютере с использованием для проверки подлинности на каждом из компьютеров учетных записей различных типов работа приложения может различаться. Предположим, приложение разрабатывается на компьютере под управлением Windows XP Professional Edition с использованием режима проверки подлинности SSPI Negotiated. Если для проверки подлинности используется учетная запись локального пользователя, будет использоваться протокол NTLM. После разработки приложения служба развертывается на компьютере под управлением Windows Server 2003, где она выполняется от имени учетной записи домена. В этом случае клиент не сможет пройти проверку подлинности на стороне службы, поскольку будут использоваться протокол Kerberos и контроллер домена.
См. также
Справочник
WindowsClientCredential
WindowsServiceCredential
WindowsClientCredential
ClientBase
Основные понятия
Делегирование и олицетворение с использованием WCF
Неподдерживаемые сценарии