Отладка ошибок проверка подлинности Windows
При использовании в качестве механизма обеспечения безопасности проверки подлинности Windows процессы безопасности обрабатываются интерфейсом поставщика поддержки безопасности SSPI. При возникновении ошибок безопасности на уровне SSPI они отображаются Windows Communication Foundation (WCF). В этом разделе описаны общие принципы и некоторые вопросы, помогающие диагностировать такие ошибки.
Общие сведения о протоколе Kerberos см. в статье Kerberos. Общие сведения об SSPI см. в статье SSPI.
Для проверка подлинности Windows WCF обычно использует поставщик поддержки безопасности согласований (SSP), который выполняет взаимную проверку подлинности Kerberos между клиентом и службой. Если протокол Kerberos недоступен, по умолчанию WCF возвращается в NT LAN Manager (NTLM). Однако вы можете настроить WCF для использования только протокола Kerberos (и вызвать исключение, если Kerberos недоступен). Вы также можете настроить WCF для использования ограниченных форм протокола Kerberos.
Методология отладки
Базовый метод отладки состоит в следующем.
Определите, используется ли проверка подлинности Windows. Если используется какая-либо другая схема, этот раздел неприменим к такому сценарию.
Если вы уверены, что используете проверка подлинности Windows, определите, использует ли конфигурация WCF прямую или согласование Kerberos.
После определения протокола, который используется в текущей конфигурации (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-адреса службы. В этом случае предполагается, что учетная запись, в которой запущена служба, имеет доступ к ключу субъекта-службы (по умолчанию), созданному при добавлении компьютера в домен Active Directory, который чаще всего выполняется путем запуска службы в учетной записи сетевой службы. Если у службы нет доступа к ключу имени участника-службы этого компьютера, необходимо предоставить правильное имя участника-службы или имя участника-пользователя (UPN) учетной записи, под которой выполняется служба в удостоверении конечной точки клиента. Дополнительные сведения о том, как WCF работает с поставщиком удостоверений и удостоверений служб, см. в разделе "Идентификация службы" и "Проверка подлинности".
В сценариях с балансировкой нагрузки, например при использовании веб-ферм или веб-садов, распространена практика определения уникальной учетной записи для каждого из приложений, назначения этой учетной записи имени участника-службы и контроль за тем, чтобы все службы приложения выполнялись от имени этой учетной записи.
Чтобы получить для учетной записи службы имя участника-службы, нужны права администратора домена Active Directory. Дополнительные сведения см . в техническом дополнение Kerberos для Windows.
Для непосредственного применения протокола Kerberos необходимо, чтобы служба выполнялась от имени учетной записи компьютера домена
Такая ситуация возникает, когда свойство 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
Чтобы решить эту проблему, запустите службу от имени учетной записи компьютера домена, например учетной записи 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
. Этот атрибут содержится в окнах<>.
Протокол 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 от имени встроенной учетной записи SYSTEM.
Другие проблемы
Учетные данные клиента заданы неверно
При проверке подлинности 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.
Разработка и развертывание с использованием различных удостоверений
В случае разработки приложения на одном компьютере и его развертывания на другом компьютере с использованием для проверки подлинности на каждом из компьютеров учетных записей различных типов работа приложения может различаться. Предположим, приложение разрабатывается на компьютере под управлением Windows XP Professional Edition с использованием режима проверки подлинности SSPI Negotiated
. Если для проверки подлинности используется учетная запись локального пользователя, будет использоваться протокол NTLM. После разработки приложения служба развертывается на компьютере под управлением Windows Server 2003, где она выполняется от имени учетной записи домена. На этом этапе клиент не сможет пройти проверку подлинности службы, так как он будет использовать Kerberos и контроллер домена.