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& 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& 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& 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- *协议的较简单场景。
.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
非常感谢! – jamiebarrow 2012-09-12 11:53:14
这是有道理的,但请看到我上面的结果editied问题。谢谢 – NealWalters 2009-11-03 19:18:40
如果没有关于您的服务需求的更明确信息,很难说出究竟究竟发生了什么,但是您无法真正依靠向导来获得正确的结果。你可以从一个干净的WSHttp发送端口开始,看看你是否可以使用SecurityMode == Message,MessageClientCredentialType == Username? 至于NegotiateServiceCredential的事情,我不确定WSE3是否支持,所以你可能需要禁用它并手动配置服务器证书。 – tomasr 2009-11-04 12:08:03