Этот вопрос уже обсуждался пару раз на SO, но я не смог найти подходящего решения для моей проблемы. У меня есть служба WCF, размещенная на внешнем сервере (другой домен), и я пытаюсь использовать его из приложения командной строки. Я получаю следующую ошибку:
The request for security token could not be satisfied because authentication failed.
Служба настроена в файле web.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_IRun">
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://www.domain.net"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="calculadora.SOA.RunBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="calculadora.SOA.RunBehavior" name="calculadora.SOA.Run">
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc" binding="wsHttpBinding" contract="calculadora.SOA.IRun">
<identity>
<dns value="domain.net"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
На стороне клиента я создаю пользовательскую привязку для подключения к службе. Вот конфигурация безопасности:
standardBinding.Security.Mode = SecurityMode.None;
standardBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
standardBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
standardBinding.Security.Transport.Realm = "";
standardBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
standardBinding.Security.Message.NegotiateServiceCredential = false;
standardBinding.Security.Message.EstablishSecurityContext = false;
standardBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
Я не использую какой-либо механизм безопасности для аутентификации, но служба, похоже, ожидает его. При работе на разных доменах обязательно ли использовать базовую аутентификацию?
РЕДАКТИРОВАТЬ: Я не ссылался ни на какую конфигурацию привязки в моей конечной точке. Как только ссылка была установлена, я получил другое сообщение об ошибке:
{"The message with Action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue' cannot be processed at the
receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract
mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the
receiver. Check that sender and receiver have the same contract and the same binding (including security
requirements, e.g. Message, Transport, None)."}
Проблема была вызвана привязкой моего клиента. Когда я создавал свою пользовательскую привязку с использованием стандартного WSHttpBinding, для свойства SecurityMode было установлено значение «Сообщение» вместо «Нет». Теперь код выглядит следующим образом, и служба наконец работает:
WSHttpBinding standardBinding = new WSHttpBinding(SecurityMode.None, false);
CustomBinding myCustomBinding = new CustomBinding(standardBinding);
Большое спасибо marc_s!