WSHttpBinding TransportWithMessageCredential SecurityMode изменяет запрос

Я борюсь с конфигурациями привязки WCF. У меня есть сторонняя служба, добавленная в качестве ссылки на мой проект. Мне предоставили некоторые характеристики.

Мне нужно использовать SOAP v1.2, поэтому я решил, что мне нужно WSHttpBinding, это будет https, поэтому мне нужно SecurityMode.Transport

Что-то вроде этого:

var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
var client = new MyClient(binding, addr);
var result = client.Method(new MyObject());

Это приводит к этому телу запроса.

 <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"      
            xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
  <S:Header>
     <wsa:MessageID>
       uuid:6B29FC40-CA47-1067-B31D-00DD010662DA
     </wsa:MessageID>
     <wsa:ReplyTo>
       <wsa:Address>example</wsa:Address>
     </wsa:ReplyTo>
     <wsa:To>example</wsa:To>
     <wsa:Action>example</wsa:Action>
  </S:Header>
  <S:Body>
     <MyObject>...</MyObject>
  </S:Body>
 </S:Envelope>

В соответствии со спецификацией, которую мне предоставили, мне нужно включить элемент Security в заголовок с UsernameToken и Timestamp. Именно то, что я получил бы с BasicHttpBinding и BasicHttpSecurityMode.TransportWithMessageCredential

Когда я пытаюсь установить режим TransportWithMessageCredential с WSHttpBinding, тело запроса резко меняется.

binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var client = new MyClient(binding, addr);
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "123456";
var result = client.Method(new MyObject());
 <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"      
            xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
  <S:Header>
     <wsa:MessageID>
       uuid:b633067e-9a9e-4216-b036-4afa3aca161e
     </wsa:MessageID>
     <wsa:ReplyTo>
       <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
     </wsa:ReplyTo>
     <wsa:To>example</wsa:To>
     <wsa:Action>http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</wsa:Action>
     <o:Security s:mustUnderstand=1 xmlns:o=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd>
      <u:Timestamp>...<u:Timestamp>
      <o:UsernameToken>
      <o:Username>...</o:Username>
      <o:Password>...</o:Password>
      </o:UsernameToken>
     </o:Security>
  </S:Header>
  <S:Body>
     <t:RequestSecurityToken>...</t:RequestSecurityToken>
  </S:Body>
 </S:Envelope>

Теперь у меня правильная часть безопасности, но вся адресная часть неверна и тело тоже. Что я должен делать?

Я ожидал (и мне нужно) что-то вроде этого:

 <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"      
            xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
  <S:Header>
     <wsa:MessageID>
       uuid:6B29FC40-CA47-1067-B31D-00DD010662DA
     </wsa:MessageID>
     <wsa:ReplyTo>
       <wsa:Address>example</wsa:Address>
     </wsa:ReplyTo>
     <wsa:To>example</wsa:To>
     <wsa:Action>example</wsa:Action>
     <o:Security s:mustUnderstand=1 xmlns:o=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd>
      <u:Timestamp>...<u:Timestamp>
      <o:UsernameToken>
      <o:Username>...</o:Username>
      <o:Password>...</o:Password>
      </o:UsernameToken>
     </o:Security>
  </S:Header>
  <S:Body>
     <MyObject>...</MyObject>
  </S:Body>
 </S:Envelope>

person Kapitán Mlíko    schedule 30.12.2016    source источник
comment
Я рекомендую вам попробовать шаги, указанные в заголовке stackoverflow.com/questions/25776403/   -  person mfatih    schedule 02.01.2017


Ответы (2)


Второй отправленный вами пакет — это не запрос вызова WCF, а часть настройки канала безопасности. Это пакет RequestSecurityToken, ответом на который будет RequestSecurityTokenResponse. После этого, если канал настроен правильно, будет отправлен тот же пакет с вызовом метода, который вы разместили в первом фрагменте. Вы можете увидеть эту последовательность пакетов в Service Trace Viewer:

введите здесь описание изображения

Какую реальную проблему вы пытаетесь решить? Ваш вызов WCF терпит неудачу? Если да, пожалуйста, предоставьте подробную информацию об исключении. Наиболее вероятная причина — ошибка конфигурации или аутентификации WCF.

Если вы стремитесь избегать этих пакетов согласования, проверьте этот ответ, в котором показано, как переключить SecurityMode на Message и установить для параметра NegotiateServiceCredential значение false. .

ОБНОВЛЕНИЕ:

Эта часть связана с обновлением вопроса, в котором предлагается исправить адресную часть запроса.

Чтобы вручную установить заголовок wsa:ReplyTo, вам необходимо установить ReplyTo свойство OperationContext.OutgoingMessageHeaders< /а>, вот так:

using (new OperationContextScope(client.InnerChannel))
{
    OperationContext.Current.OutgoingMessageHeaders.ReplyTo = new EndpointAddress("http://someclient/callback");
    var request = client.Method(new MyObject());
}

Дополнительные сведения см. в этом ответе.

person CodeFuller    schedule 03.01.2017
comment
спасибо за ваш ответ. Я обновил вопрос и предоставил тело запроса, которое мне нужно. - person Kapitán Mlíko; 03.01.2017

В конце концов мне пришлось использовать CustomBinding для отправки желаемого запроса.

var b = new CustomBinding();

var security = TransportSecurityBindingElement.CreateUserNameOverTransportBindingElement();
    security.IncludeTimestamp = true;
    security.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
    security.MessageSecurityVersion = MessageSecurityVersion.Default;
    security.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
    security.EnableUnsecuredResponse = true;

var encoding = new TextMessageEncodingBindingElement();
    encoding.MessageVersion = MessageVersion.Soap12WSAddressing10;

var transport = new HttpsTransportBindingElement
    {
       MaxBufferPoolSize = 2147483647,
       MaxBufferSize = 2147483647,
       MaxReceivedMessageSize = 2147483647,
    };

    b.Elements.Add(security);
    b.Elements.Add(encoding);
    b.Elements.Add(transport);

var client = new MyClient(binding, addr);
var result = client.Method(new MyObject());
person Kapitán Mlíko    schedule 09.01.2017