WCF 客户端 - 如何处理或忽略 MustUnderstand header 元素?

标签 wcf web-services jboss wcf-binding ws-security

我正在写一个 WCF使用 WS-Security 使用非 .Net Web 服务的客户端。服务的响应包含一个将 mustUnderstand 设置为 true 的 Security header 。

使用 ServiceModelListener,我确实看到了从服务返回的实际数据。但是,WCF 客户端失败,因为它没有处理安全 header 。

<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 客户端错误消息:

The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.



我的 WCF客户端不需要任何时间戳信息。是否有一种简单的方法可以在处理例程中 stub ?我已经尝试扩展 Response 类并添加 [MessageHeader] 属性。

编辑:

Asked another way: How do I implement a WCF client that accepts custom header elements that are marked Must Understand?

最佳答案

我遇到了类似的问题。我不确定这是否有用。

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 设置为 None。
 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 并为消息检查器添加了一个端点行为。
在这一点上,我可以控制请求,我可以添加适当的 header 并修改 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);

我还必须修改操作标题
 else if (localName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
            {
                foreach (XAttribute a in element.Attributes())
                {
                    if (a.Name.LocalName == "mustUnderstand")
                        a.Value = "0";
                }
            }

我的问题是该服务没有回复 Action Header

所以在
 public void AfterReceiveReply

我调用了我的 TransformReply 返回类型 Message ,如下所示。您可能需要修改 string.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 文件并将其放置在首选项的 SSLSettings 中。

关于WCF 客户端 - 如何处理或忽略 MustUnderstand header 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9909777/

相关文章:

javascript - 如何将字节数组转换为图像?

c# - Monotouch 和 WCF : difference of SVCUTIL. EXE 和 SLSVCUTIL.EXE 以及如何避免不受支持的通用 ChannelFactory?

java - 构建工作区期间的 StackOverflowError

c# - 在 WCF 中使用泛型时客户端出现奇怪的类型

java - Glassfish 4.1 : war inside ear does not expose webservices

web-services - 使用 CodeIgniter API 进行身份验证

c# - C#.Net Web服务错误处理

java - 使用 JBoss 或 Tomcat 的独立应用程序

spring - 配置问题 : Unable to locate Spring NamespaceHandler for XML schema namespace [http://www. springframework.org/schema/tx]

wcf - WCF Duplex 是一个不错的选择吗?