BizTalk SendPort WCF使用WS-Security调用.asmx Web服务 [英] BizTalk SendPort WCF Calling .asmx web service using WS-Security

查看:81
本文介绍了BizTalk SendPort WCF使用WS-Security调用.asmx Web服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我发现的所有内容都表明我应该能够使用WCF调用使用WS-Security的.asmx Web服务.问题是如何配置WCF端口.我正在使用WCF-BasicHttp.首先,可以吗?其次,如何正确输入用户名/密码.在安全标签上,我应该选择哪种安全模式"?

Everything I've found so far says I should be able to use WCF to call a .asmx web service that uses WS-Security. The question is how to configure the WCF-Port. I'm using WCF-BasicHttp. First of all, is that okay? Second, how to enter the user/pass properly. On the security tab, which "Security Mode" should I pick?

似乎唯一让我输入凭据的是TransportWithMessageCredential,然后我可以通过用户名凭据单击编辑"按钮并输入用户/密码.

The only one that seems to let me enter credentials is TransportWithMessageCredential, then I can click the "Edit" button by username credentials and enter a user/pass.

但是当我这样做的时候,我得到了:

But when I did, I got this:

<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绑定:

Follow-up to TomasR's post - using WS-HTTP binding:

1)BizTalk使用WCF向导"构建了一个自定义绑定文件和一个WS-BasicHTTP绑定文件,因此我更改了SendPort,并手动复制了所有配置.

1) BizTalk "Consume WCF Wizard" builds a custom binding file and a WS-BasicHTTP Binding file, so I changed SendPort, and manually copied over all the configurations.

设置如下:
安全模式:消息
邮件客户端凭据类型:UseName
算法套件:Basic256 [我不知道在这里放什么]
我还选中了另外两个框:
a)协商服务凭证[如果我不检查此凭证,则需要缩略图"]
b)建立安全上下文[也尝试不检查这一点]

Set as follows:
Security Mode: Message
Message Client Credential Type: UseName
Algorithm Suite: Basic256 [I had no idea what to put here]
I also checked two other boxes:
a) Negotiate service credential [if I don't check this, it wants a "thumbprint"]
b) Establish security context [also tried not checking this one]

2)然而出现此错误:

2) Ran and got this error:

说明:
适配器无法发送消息,该消息将发送带有URL" http://的端口" WcfSendPort_ValuationServicePort_ValuationServicePortSoap"rct3.msbexpress.net/demo/ExpressLync/ValuationService.asmx ".在为此发送端口指定的重试间隔后,将重新发送该消息.
详细信息:"System.NullReferenceException:对象引用未设置为对象的实例.

Description:
The adapter failed to transmit message going to send port "WcfSendPort_ValuationServicePort_ValuationServicePortSoap" with URL "http://rct3.msbexpress.net/demo/ExpressLync/ValuationService.asmx". It will be retransmitted after the retry interval specified for this Send Port.
Details:"System.NullReferenceException: Object reference not set to an instance of an object.

服务器堆栈跟踪:

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]:

Exception rethrown at [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)".  


现在尝试自定义绑定,添加用户/密码并得到以下错误:


Now tried custom binding, added user/pass and get this error:

<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中:


My next attempt, went back to WS-HTTP, but tried to put the User/Pass in a message assignment rather than in the 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票证:


Fifth attempt, about to give up and open a Microsoft ticket:

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

与第四次尝试相同的错误.

same error as fourth attempt.

根据提供Web服务的供应商的文档,我应该将用户放在W-Security UsernameToken元素中,将密码放在WS-Security密码中,并将该元素的属性设置为"PasswordDigest".它还说:该令牌应添加到Web方法的SOAP请求中."我不确定这是如何从旧的WSE3天转换为新的WCF天.

According to the doc of the vendor providing the web service, I should put the user in W-Security UsernameToken element, the password in WS-Security password, and set the element's attribute to "PasswordDigest". It also says "This token should be added to the SOAP request for the Web method." I'm not sure how this translates from the old WSE3 days to the new WCF days.

推荐答案

使用自定义绑定,然后从BizTalk发送端口中,单击配置",然后转到最右边的选项卡,其中显示导入/导出".将以下XML粘贴到文件(sample.config)中,然后将其导入配置端口.这基本上节省了在绑定"选项卡上手动键入很多内容的时间.

Use custom binding, and from the BizTalk send port, click configure, then go to the right-most tab which says "Import/Export". Paste the following XML into a file (sample.config) and then import it into the configuration port. This basically saves the time of manually typing a lot of stuff on the binding tab.

<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的链接,该链接描述了更多详细信息).

The above is not very intuitive (I'm still waiting for a link from Microsoft which describes this is more detail).

然后,您仍然在凭据标签上指定用户/密码.

Then you still specify the user/pass on the credentials tab.

但是,这给我们造成了一个问题,因为我们调用的供应商的.asmx Web服务没有将IIS设置为需要SSL".显然,这是与WCF一起使用的要求.换句话说,它与WSE3将.NET调用到.NET一起正常工作,但是当尝试将WCF调用到.asmx时,WCF的要求稍微严格一些.

However, this caused a problem for us, in that the vendor's .asmx web service we were calling did not have IIS set to "requires SSL". Apparently, that is a requirement for this to work with WCF. In other words, it works fine with WSE3 calling .NET to .NET, but when trying to call WCF to .asmx, WCF has a slightly more stringent requirement.

尼尔·沃尔特斯

这篇关于BizTalk SendPort WCF使用WS-Security调用.asmx Web服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆