#c# #wcf
#c# #wcf
Вопрос:
В настоящее время мы переносим службы старого приложения WCF на серверы в новом домене. С момента миграции время от времени возникает упомянутая ниже ошибка.
Произошло исключение…
Сведения об исключении: сервер отклонил учетные данные клиента.
Система.ServiceModel.Исключение FaultException`1[System.ServiceModel.ExceptionDetail]: сервер отклонил учетные данные клиента. (Информация об ошибке равна ExceptionDetail, вероятно, созданной IncludeExceptionDetailInFaults=true , значение которого равно:
Система.ServiceModel.Безопасность.Исключение SecurityNegotiationException: сервер отклонил учетные данные клиента.
Система.Безопасность.Аутентификация.Исключение InvalidCredentialException: сервер отклонил учетные данные клиента.
Система.ComponentModel.Win32Exception: попытка входа в систему завершилась неудачно — Конец внутренней трассировки стека исключений —
в System.Net.Security.NegoState.ProcessReceivedBlob(сообщение Byte[], LazyAsyncResult lazyResult)
в System.Net.Security.NegoState.StartSendBlob(сообщение Byte[], LazyAsyncResult lazyResult)
в System.Net.Security.NegoState.StartSendBlob(сообщение Byte[], LazyAsyncResult lazyResult)
в System.Net.Security.NegoState.Проверка подлинности процесса (LazyAsyncResult lazyResult)
в System.Net.Security.NegotiateStream.Аутентифицируйте клиента (учетные данные NetworkCredential, строковое целевое имя, требуемый уровень защиты, разрешенный уровень токенизации)
на …).
Сложность в том, что все вызовы выполняются в 95% случаев, и нет прозрачной причины внезапного сбоя вызова.
Конфигурации и вызовы выглядят следующим образом:
Вызывающий:
<binding name="Binding_ServiceTCP"
closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="infinite" sendTimeout="infinite"
transferMode="Buffered" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
<Channel ChannelType="IWcfInterface" Name="ServiceName"
Binding="Binding_ServiceTCP" Address="net.tcp://serverinnewdomain:59886/Service" Identity="" />
objectOfIWcfInterfaceImplementingClass.WcfCall();
Получатель:
<service behaviorConfiguration="BehaviourName" name="ServiceName">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="Binding_ServiceTCP" contract="IWcfInterface" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://serverinnewdomain:59886/Service" />
</baseAddresses>
</host>
</service>
<behavior name="BehaviourName">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
<binding name="Binding_ServiceTCP"
closeTimeout="00:30:00" openTimeout="00:30:00"
receiveTimeout="infinite" sendTimeout="infinite"
transferMode="Buffered" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
<readerQuotas maxDepth="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
[ServiceContract(Namespace = "http://some.cool/namespace")]
[XmlSerializerFormat]
public interface IWcfInterface
{
[OperationContract]
[XmlSerializerFormat(SupportFaults = true)]
SomeClass WcfCall();
}
Реализация зарегистрирована через замок.
container.Register(Component.For<IWcfInterface>().ImplementedBy<WcfClass>().LifeStyle.PerWcfOperation());
на старых серверах установлена .NET 4.7, на новых — 4.8.
Подозревая, что учетные данные где-то потеряны на пути от вызывающего абонента к получателю, я связался с сетевой командой, но они сказали мне, что это невозможно.
Я хотел бы видеть, какие учетные данные поступают в службу. Если это невозможно, я также был бы доволен любым другим решением.
Ответ №1:
Во многом это связано с несоответствием домена Windows, и есть два решения:
-
Поместите сервер приложений и клиент в один и тот же домен Windows.
-
Если компьютеры находятся в одном домене, убедитесь, что учетная запись пользователя, используемая для запуска службы, является учетной записью домена, а не учетной записью локального сервера.
Обратите внимание, что если вы используете проверку подлинности Windows, клиентский домен и сервер должны находиться в одном домене Windows.
Другое решение — не использовать проверку подлинности Windows:
<bindings>
<netTcpBinding>
<binding name="TcpBinding">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
Комментарии:
1. Режим безопасности = «Нет» для одного конкретного канала спасает положение! Спасибо миллион