BizTalk SendPort WCF Вызов веб-службы .asmx с использованием WS-Security

Все, что я нашел до сих пор, говорит о том, что я могу использовать WCF для вызова веб-службы .asmx, которая использует WS-Security. Вопрос в том, как настроить WCF-порт. Я использую WCF-BasicHttp. Прежде всего, это нормально? Во-вторых, как правильно ввести пользователя / пароль. Какой «Режим безопасности» выбрать на вкладке «Безопасность»?

Единственный, который, кажется, позволяет мне вводить учетные данные, - это TransportWithMessageCredential, затем я могу нажать кнопку «Изменить» с помощью учетных данных имени пользователя и ввести пользователя / пароль.

Но когда я это сделал, я получил следующее:

<soap:Fault xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <faultcode xmlns:q0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">q0:Security</faultcode>
   <faultstring>Microsoft.Web.Services3.Security.SecurityFault: Security requirements are not satisfied because the security header is not present in the incoming message.
   at Microsoft.Web.Services3.Design.UsernameOverTransportAssertion.ServiceInputFilter.ValidateMessageSecurity(SoapEnvelope envelope, Security security)
   at MSB.RCTExpress.Presentation.Web.UsernameOverTransportAssertion.ServiceInputFilter.ValidateMessageSecurity(SoapEnvelope envelope, Security security)
     in C:\projects\la1safe1\RCT Express\MSB.RCTExpress\3.10\Presentation.Web\UsernameOverTransportNoSendNone.cs:line 27
   at Microsoft.Web.Services3.Security.ReceiveSecurityFilter.ProcessMessage(SoapEnvelope envelope)
   at Microsoft.Web.Services3.Pipeline.ProcessInputMessage(SoapEnvelope envelope)
   at Microsoft.Web.Services3.WseProtocol.FilterRequest(SoapEnvelope requestEnvelope)
   at Microsoft.Web.Services3.WseProtocol.RouteRequest(SoapServerMessage message)
   at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean&amp; abortProcessing)</faultstring>
   <faultactor>http://rct3.msbexpress.net/demo/ExpressLync/ValuationService.asmx</faultactor>
</soap:Fault>

Любые идеи?

Спасибо,

Нил Уолтерс

Продолжение сообщения TomasR - использование привязки WS-HTTP:

1) BizTalk «Мастер использования WCF» создает файл настраиваемой привязки и файл привязки WS-BasicHTTP, поэтому я изменил SendPort и вручную скопировал все конфигурации.

Установите следующее:
Режим безопасности: Сообщение
Тип учетных данных клиента сообщений: UseName
Набор алгоритмов: Basic256 [я понятия не имел, что сюда помещать]
Я также поставил два других флажка:
a) Согласование учетных данных службы [если я не проверю это, ему нужен "отпечаток пальца"]
b) Установите контекст безопасности [также пытался не проверять этот]

2) Запустил и получил такую ​​ошибку:

Описание:
Адаптеру не удалось передать сообщение для отправки порта "WcfSendPort_ValuationServicePort_ValuationServicePortSoap" с URL-адресом "http://rct3.msbexpress.net/demo/ExpressLync/ValuationService.asmx ". Он будет передан повторно после интервала повтора, указанного для этого порта отправки.
Подробности: «System.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта.

Трассировка стека сервера:

at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)  
at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)  
at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout)  
at System.ServiceModel.Security.SecurityUtils.OpenTokenProviderIfRequired(SecurityTokenProvider tokenProvider, TimeSpan timeout)  
at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)  
at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)  
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation,   
  EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)  
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)  
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)  
at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)  
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)  
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)  
at System.ServiceModel.Channels.CommunicationObject.Open()

Исключение повторно генерируется на [0]:

at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)  
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)  
at System.ServiceModel.ICommunicationObject.Open()  
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.GetChannel[TChannel](IBaseMessage bizTalkMessage,   
  ChannelFactory`1& cachedFactory)  
at Microsoft.BizTalk.Adapter.Wcf.Runtime.WcfClient`2.SendMessage(IBaseMessage bizTalkMessage)".  

Теперь попробовал настраиваемую привязку, добавил пользователя / проход и получил эту ошибку:

<soap:Fault xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Code>
    <soap:Value xmlns:q0="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">q0:Security</soap:Value>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Microsoft.Web.Services3.Security.SecurityFault: 
  Security requirements are not satisfied because the security header is not present in the incoming message.
  at Microsoft.Web.Services3.Design.UsernameOverTransportAssertion.ServiceInputFilter.ValidateMessageSecurity(SoapEnvelope envelope, 
    Security security)
  at MSB.RCTExpress.Presentation.Web.UsernameOverTransportAssertion.ServiceInputFilter.ValidateMessageSecurity
    (SoapEnvelope envelope, Security security) in 
    C:\projects\la1safe1\RCT Express\MSB.RCTExpress\3.10\Presentation.Web\UsernameOverTransportNoSendNone.cs:line 27
  at Microsoft.Web.Services3.Security.ReceiveSecurityFilter.ProcessMessage(SoapEnvelope envelope)
  at Microsoft.Web.Services3.Pipeline.ProcessInputMessage(SoapEnvelope envelope)
  at Microsoft.Web.Services3.WseProtocol.FilterRequest(SoapEnvelope requestEnvelope)
  at Microsoft.Web.Services3.WseProtocol.RouteRequest(SoapServerMessage message)
  at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
  at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
  at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean&amp; abortProcessing)</soap:Text>
</soap:Reason>
<soap:Node>http://rct3.msbexpress.net/demo/ExpressLync/ValuationService.asmx</soap:Node>
</soap:Fault>

Моя следующая попытка вернулась к WS-HTTP, но попыталась поместить User / Pass в назначение сообщения, а не в SendPort:

msgRCTGetRequest(SOAP.Username) = "myuser"; 
msgRCTGetRequest(SOAP.Password) = "mypass"; 
//msgRCTGetRequest(SOAP.UseSoap12) = true; 

В результате возникла эта ошибка:

<soap:Fault xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Code>
<soap:Value>soap:Sender</soap:Value>
</soap:Code><soap:Reason>
<soap:Text xml:lang="en">System.Web.Services.Protocols.SoapHeaderException: WSE012: The input was not a valid SOAP message because the following information is missing: action.
   at Microsoft.Web.Services3.Utilities.AspNetHelper.SetDefaultAddressingProperties(SoapContext context, HttpContext httpContext)
   at Microsoft.Web.Services3.WseProtocol.CreateRequestSoapContext(SoapEnvelope requestEnvelope)
   at Microsoft.Web.Services3.WseProtocol.FilterRequest(SoapEnvelope requestEnvelope)
   at Microsoft.Web.Services3.WseProtocol.RouteRequest(SoapServerMessage message)
   at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean&amp; abortProcessing)</soap:Text>
</soap:Reason>
</soap:Fault>

Пятая попытка, собираюсь сдаться и открыть билет Microsoft:

msgRCTGetRequest(WCF.UserName) = "myuser";
msgRCTGetRequest(WCF.Password) = "mypass";
msgRCTGetRequest(WCF.Action)      = "GetPropertyInfoSourceRecordPolicyNum"; 
msgRCTGetRequest(SOAP.MethodName) = "GetPropertyInfoSourceRecordPolicyNum"; 
msgRCTGetRequest(SOAP.Username) = "myuser"; 
msgRCTGetRequest(SOAP.Password) = "mypass"; 

та же ошибка, что и при четвертой попытке.


Согласно документу поставщика, предоставляющего веб-сервис, я должен поместить пользователя в элемент W-Security UsernameToken, пароль в пароль WS-Security и установить для атрибута элемента значение «PasswordDigest». В нем также говорится: «Этот токен следует добавить в запрос SOAP для веб-метода». Я не уверен, как это переводится со старых дней WSE3 на новые дни WCF.


person NealWalters    schedule 03.11.2009    source источник


Ответы (3)


Нил, для WS-Security необходимо использовать привязку / адаптер WCF-WsHttp. WCF-BasicHttp предназначен только для более простых сценариев, когда протоколы WS- * не нужны.

person tomasr    schedule 03.11.2009
comment
Это имеет смысл, но, пожалуйста, посмотрите мой результат в отредактированном вопросе выше. Спасибо - person NealWalters; 03.11.2009
comment
Трудно сказать, что именно происходит, без более четкой информации о том, что требуется вашей службе, но вы не можете действительно полагаться на мастеров, чтобы понять это правильно. Можете ли вы начать с чистого порта отправки WSHttp и посмотреть, сможете ли вы заставить его работать, используя SecurityMode == Message, MessageClientCredentialType == Username? Что касается NegotiateServiceCredential, я не уверен, что WSE3 поддерживает это, поэтому вам может потребоваться отключить его и вручную настроить сертификат сервера в конфигурации. - person tomasr; 04.11.2009

.NET 4.0 и .NET 3.5 SP1 с исправлением 971831 позволяют WS-Security через транспорт http. Попробуйте использовать этот образец привязки:

       <customBinding>
        <binding name="httpAndWSSecurity">
          <security authenticationMode="UserNameOverTransport" 
                    allowInsecureTransport="true"/> 
          <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004"  />
          <httpTransport/>
        </binding>

Также см. эту статью MSDN о SecurityBindingElement.AllowInsecureTransport < / а>

person TerryDunnigan    schedule 08.07.2010

Используйте настраиваемую привязку и в порту отправки BizTalk нажмите кнопку «Настроить», затем перейдите на крайнюю правую вкладку с надписью «Импорт / экспорт». Вставьте следующий XML-код в файл (sample.config), а затем импортируйте его в порт конфигурации. Это в основном экономит время, необходимое для ручного ввода большого количества данных на вкладке привязки.

<configuration>
  <system.serviceModel>
    <client>
      <endpoint
       address="http://rct3.msbexpress.net/demo/ExpressLync/ValuationService.asmx"
       binding="customBinding"
       bindingConfiguration="ValuationServicePortSoap12"
       contract="BizTalk"
       name="WcfSendPort_ValuationServicePort_ValuationServicePortSoap12"/>
    </client>
    <bindings>
     <customBinding>
      <binding name="ValuationServicePortSoap12">
       <security authenticationMode="UserNameOverTransport"
        messageProtectionOrder="SignBeforeEncrypt"
        includeTimestamp="true"
        messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
        requireDerivedKeys="false"
        requireSignatureConfirmation="false"/>
       <textMessageEncoding messageVersion="Soap11WSAddressingAugust2004"/>
       <httpsTransport />
      </binding>
     </customBinding>
    </bindings>
   </system.serviceModel>
</configuration>

Вышесказанное не очень интуитивно понятно (я все еще жду ссылки от Microsoft, которая описывает это более подробно).

Затем вы все равно указываете пользователя / проход на вкладке учетных данных.

Однако это вызвало у нас проблему, поскольку веб-служба поставщика .asmx, которую мы вызывали, не имела для IIS значения «требует SSL». По-видимому, это требование для работы с WCF. Другими словами, он отлично работает с WSE3, вызывающим .NET в .NET, но при попытке вызвать WCF в .asmx WCF предъявляет несколько более жесткие требования.

Нил Уолтерс

person NealWalters    schedule 04.11.2009