У меня есть приложение, которое подключается через https к веб-службе на основе SOAP, которая реализует WS-Security. Веб-сервис написан на Java, ожидает простой текстовый пароль, а также правильно установленную метку времени.
После долгих поисков и поисков я не могу понять, как настроить мой клиент WCF для взаимодействия с этим сервисом. В дополнение к правильному ответу, я также был бы признателен за ссылку на учебное пособие, которое хорошо объясняет WCF и SOAP.
app.config моего текущего клиента выглядит так:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyServiceSoapBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
<!--security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security-->
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://p1.my.com/tx/services/MyService"
binding="basicHttpBinding" bindingConfiguration="MyServiceSoapBinding"
contract="My.IMyService" name="MyServiceEndpointPort" />
</client>
</system.serviceModel>
</configuration>
и код клиента выглядит следующим образом:
string response;
try
{
MyService.MyServiceClient svc = new WcfExample.MyService.MyServiceClient();
svc.ClientCredentials.UserName.UserName = "myUser";
svc.ClientCredentials.UserName.Password = "myPass";
response = svc.ping();
lblPingResponse.Text = response;
}
catch (System.ServiceModel.Security.MessageSecurityException mse)
{
lblPingResponse.Text = "MessageSecurityException: " + mse.Message;
}
catch (Exception ex)
{
lblPingResponse.Text = "Exception: " + ex.Message;
}
Этот код выдает это исключение:
MessageSecurityException "Безопасность
процессор не смог найти
заголовок безопасности в сообщении. это
может быть потому, что сообщение является
необеспеченная ошибка или потому, что есть
несоответствие между
общающиеся стороны. Это может
происходят, если служба настроена для
безопасность и клиент не использует
безопасности. "
Для работы версии WSE 3 требуется следующее:
ServiceUsernameTokenManager.AddUser(userName, password);
UsernameToken token = new UsernameToken(userName, password,
PasswordOption.SendPlainText);
proxy = new _MyServiceWse();
Policy policy = new Policy();
policy.Assertions.Add(new UsernameOverTransportAssertion());
policy.Assertions.Add(new RequireActionHeaderAssertion());
proxy.SetPolicy(policy);
proxy.SetClientCredential(token);
UPDATE:
Запрос теперь достигает сервера, и ответ отправляется обратно с сервера с использованием этой конфигурации в app.config:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
Затем клиент генерирует исключение
"Не удалось найти процессор безопасности
заголовок безопасности в сообщении. это
может быть потому, что сообщение является
необеспеченная ошибка или потому, что есть
несоответствие между
общающиеся стороны. Это может
происходят, если служба настроена для
безопасность и клиент не использует
безопасности. "
Это происходит потому, что клиент отправляет заголовок метки времени, но служба не возвращает заголовок метки времени. Это, вероятно, «правильная вещь», но она не очень полезна, потому что там развернуто много веб-служб, которые ожидают метку времени, но не возвращают ее.
Если есть способ убедить клиента принять эту ситуацию, я бы хотел узнать об этом. А пока я посмотрю, могу ли я изменить веб-службу, чтобы она возвращала метку времени.