WCF客户端 - 如何处理或忽略MustUnderstand标头元素?
我在写一个WCF
客户端,它使用WS-Security来使用非.Net Web服务。该服务的响应包含一个将mustUnderstand设置为true的安全标头。WCF客户端 - 如何处理或忽略MustUnderstand标头元素?
使用ServiceModelListener,我确实看到从服务返回的实际数据。但是,WCF客户端失败,因为它没有处理安全性标头。
<env:Header>
<wsse:Security env:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="timestamp">
<wsu:Created>2012-03-28T13:43:54.474Z</wsu:Created>
<wsu:Expires>2012-03-28T13:48:54.474Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</env:Header>
WCF客户端错误消息:
从命名空间“http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”报头“安全”没有被该消息的接收者理解,导致无法处理该消息。此错误通常表示此消息的发件人已启用接收方无法处理的通信协议。请确保客户端绑定的配置与服务的绑定一致。
我的WCF
客户端不需要任何时间戳信息。有没有简单的方法来存储处理程序?我已经尝试扩展Response类&,添加一个[MessageHeader]属性。
编辑:
问另一种方法:如何实现一个
WCF
客户接受被标记必须了解自定义标题元素?
WS-Security存在不同的标准。因为basicHttpBinding和wsHttpBindings使用不同的安全标准,所以在客户端更改绑定可能是有意义的。
我遇到了类似的问题。我不确定这是否有用。
MSDN WCF扩展
http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx
这里的设置是基于证书,Oracle应用服务器10g和.Net消费服务。尝试弄清楚请求和响应发生了什么,使用SOAPUi非常有用。
我还没有尝试修改代码来使用basicHttpBinding,但我使用WSHttpBinding作为我在代码中配置的基础。然后使用
WSHttpBinding binding = new WSHttpBinding()
{
CloseTimeout = new TimeSpan(0, 1, 0),
OpenTimeout = new TimeSpan(0, 1, 0),
SendTimeout = new TimeSpan(0, 1, 0),
AllowCookies = false,
BypassProxyOnLocal = false,
HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
MaxBufferPoolSize = 524288,
MaxReceivedMessageSize = 65536,
MessageEncoding = WSMessageEncoding.Text,
UseDefaultWebProxy = false,
ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
{
MaxDepth = 32,
MaxArrayLength = 16384,
MaxBytesPerRead = 4096,
MaxNameTableCharCount = 16384,
MaxStringContentLength = 8192
}
};
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Transport.Realm = string.Empty;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
binding.Security.Message.EstablishSecurityContext = true;
binding.Security.Message.NegotiateServiceCredential = true;
CustomBinding customBinding = new CustomBinding();
BindingElementCollection collection = binding.CreateBindingElements();
通过用于TextMessageEncodingBindingElement设置Soap11和AddressingVersion为无毛圈绒。
foreach (BindingElement element in collection)
{
if (typeof(TextMessageEncodingBindingElement) == element.GetType())
{
TextMessageEncodingBindingElement item = element as TextMessageEncodingBindingElement;
if (null != item)
{
item.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None);
customBinding.Elements.Add(item);
}
}
else
customBinding.Elements.Add(element);
}
我使用了ChannelFactory并为Message Inspector添加了EndPoint行为。 此时我控制了请求,我可以添加适当的头并修改Action的mustUnderstand。
使用SOAPUi我把我的Message.ToString()放在SOAPUI中,并测试了请求。一旦需要的项目被添加到请求中,就会确定OAS服务器没有回答所有必要的元素。使用消息检查器进行回复,我修改了消息以包含缺少的标题。我不记得我在哪里找到了消息检查器的基本代码,但是您需要修改代码以正确使用它。
对于我的例子,这里有一些片段。
对于变换消息中
public object BeforeSendRequest
我需要修改头,所以使用for循环我抓起的XElement和添加的OASIS头和添加了To报头。
XNamespace xmlns = "http://schemas.xmlsoap.org/soap/envelope/";
XElement securityHeader = new XElement(
xmlns + "Security",
new XAttribute(xmlns + "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"),
new XAttribute(xmlns + "xmlns", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"),
new XAttribute(xmlns + "mustUnderstand", "0"));
element.Add(securityHeader);
我也不得不修改Action头
else if (localName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
{
foreach (XAttribute a in element.Attributes())
{
if (a.Name.LocalName == "mustUnderstand")
a.Value = "0";
}
}
我的问题是,该服务并未因此在
public void AfterReceiveReply
与Action头
回复我打电话给我的TransformReply返回类型消息,如下所示。您可能需要修改字符串的值.Empty,但这仅仅是一个示例。
...
Message reply = Message.CreateMessage(message.Version, null, reader);
reply.Headers.Add(MessageHeader.CreateHeader("Action", string.Empty, string.Empty, false));
reply.Properties.CopyProperties(message.Properties);
...
我真的建议使用一个工具,如SOUPUI到比布尔乱用信封,看到了答复。如果您使用SSL,则需要创建cacert文件并将其放入首选项的SSLS设置中。
谢谢Adam!看起来像有趣的信息。尽管我现在已经开始了一个不同的咨询业务,所以不能再对付这个系统。 Fyi,以前的客户最终通过不同的架构方法解决了这个问题。 – 2012-05-30 18:11:09
谢谢,但该服务只支持basicHttpBinding。 – 2012-03-28 18:15:44