BizTalk SendPort WCF使用WS-Security调用.asmx Web服务

问题描述:

到目前为止我发现的一切都表明我应该能够使用WCF调用使用WS-Security的.asmx Web服务。问题是如何配置WCF端口。我正在使用WCF-BasicHttp。首先,这样好吗?其次,如何正确输入用户/通行证。在安全选项卡上,我应该选择哪种“安全模式”?BizTalk SendPort WCF使用WS-Security调用.asmx Web服务

唯一似乎让我输入证书的是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 [我不知道要放什么东西在这里]
我还检查了其他两个盒子:
一)协商服务证书[如果我不检查这个,它要一个“指纹”]
b)建立安全上下文[也试过没有检查这一个]

2)RAN和得到这个错误:

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

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,而是试图把用户/密码的消息分配,而不是在发送端口:

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"; 

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


根据供应商提供的Web服务的医生,我应该把用户的W-安全用户名元素,WS-Security中的密码的密码,并设置元素的属性为“PasswordDigest”。它还说“应将此令牌添加到Web方法的SOAP请求中。”我不确定这是如何从旧的WSE3时代转换为新的WCF时代的。

使用自定义绑定,并从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> 

以上是不是很直观的(我仍然在等待微软描述,这是更详细的链接)。

,那么你仍然指定用户名/密码凭据选项卡上。

然而,这引起了我们的一个问题,在我们呼吁没有IIS设置供应商的的.asmx Web服务“要求SSL”。显然,这是与WCF一起工作的要求。换句话说,它可以很好地与WSE3调用.NET到.NET,但是当试图调用WCF到.asmx时,WCF有一个更严格的要求。

尼尔·沃尔特斯

Neal,对于WS-Security,您需要使用WCF-WsHttp绑定/适配器。 WCF-BasicHttp仅适用于不需要WS- *协议的较简单场景。

+0

这是有道理的,但请看到我上面的结果editied问题。谢谢 – NealWalters 2009-11-03 19:18:40

+0

如果没有关于您的服务需求的更明确信息,很难说出究竟究竟发生了什么,但是您无法真正依靠向导来获得正确的结果。你可以从一个干净的WSHttp发送端口开始,看看你是否可以使用SecurityMode == Message,MessageClientCredentialType == Username? 至于NegotiateServiceCredential的事情,我不确定WSE3是否支持,所以你可能需要禁用它并手动配置服务器证书。 – tomasr 2009-11-04 12:08:03

.NET 4.0和.NET 3.5的修补程序971831 SP1允许的WS-Security通过HTTP传输。尝试使用此示例绑定:

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

另见this MSDN article on SecurityBindingElement.AllowInsecureTransport

+0

非常感谢! – jamiebarrow 2012-09-12 11:53:14