Получил простое демонстрационное приложение WCF, которое имеет два консольных проекта - хост и клиент. Оба работают на моей машине (победа 7 бокса). Я использую netTcpBinding, который использует аутентификацию Windows.
Проблема в том, что аутентификация понижается до NTLM с kerberos, и я не могу понять, почему.
Если я использую
<clientCredentials>
<windows allowNtlm="true" />
</clientCredentials>
на стороне клиента, все круто. Но если я изменю это на false
, я получу следующее исключение:
SecurityNegotiationException: The
удаленный сервер не удовлетворяет
требование взаимной аутентификации.
Это говорит о том, что kerberos дает сбой, и, поскольку клиент не разрешает NTLM, вызов приводит к возникновению исключения.
Это проблема проекта или внешняя проблема, вызванная настройкой моей машины для разработки?
Решение:
Видимо, я должен указать идентификацию сервера в конфигурации клиента. В моем случае сервер работает под моим именем, поэтому я модифицирую клиента таким образом:
<client>
<endpoint address="net.tcp://dev7.HurrDurr.com:12345/MyService"
binding="netTcpBinding"
bindingConfiguration="MyBindingConfigurationLol"
behaviorConfiguration="HurrDurrServiceEndpoint"
contract="ShaolinCore.ICommunicationService">
<!-- start changes here -->
<identity>
<userPrincipalName value="myusername@mydomain"/>
</identity>
<!-- end changes here -->
</endpoint>
</client>
Я не уверен, почему это решает проблему. Хорошо, теперь на стороне клиента я полностью доверяю серверу (эй, я знаю этого парня!). Но так как NTLM менее безопасен, чем Kerberos, почему не наоборот? Если я не полностью доверяю серверу, я использую kerberos, иначе ntlm подойдет.
Или, OTOH, если я не полностью доверяю серверу, почему он вообще работает? «SecurityException: идентификатор конечной точки не установлен. WCF не может доверять идентификатору сервера и не будет передавать идентификатор клиента».