【问题标题】:C# .NET 4.0 WCF MessageSecurityException, "Security header is empty." when consuming a serviceC# .NET 4.0 WCF MessageSecurityException,“安全标头为空。”消费服务时
【发布时间】:2011-09-06 10:31:18
【问题描述】:

在项目中使用 WCF 和 C# 时,我收到异常 MessageSecurityException,并显示消息“安全标头为空。”。以下是响应(根据 MS Service Trace Viewer):

    <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="true"></wsse:Security>
        <wsa:Action>_WHAT_I_DID_</wsa:Action>
        <wsa:RelatesTo>_MSG_ID_OF_REQUEST_</wsa:RelatesTo>
      </soapenv:Header>
      <soapenv:Body>
        _CORRECT_BODY_
      </soapenv:Body>
    </soapenv:Envelope>

确实,安全标头是“空的”,但据我所知,根据安全标头定义,它仍然是正确的。

我也尝试过编辑绑定,但这似乎也无济于事。我还发现了一个类似的问题,启用 EnableUnsecuredResponse 会有所帮助,但在这里没有。

这是根据 SoapUI 的响应:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
   <soapenv:Header>
      <wsse:Security soapenv:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"/>
      <wsa:Action>_WHAT_I_DID_</wsa:Action>
      <wsa:RelatesTo>_REQ_MSG_ID_</wsa:RelatesTo>
   </soapenv:Header>
   <soapenv:Body>
      _CORRECT_BODY_
   </soapenv:Body>
</soapenv:Envelope>

它们几乎相同,只是它们关闭安全标头的方式不同。哪个有趣,但不应引发异常?

我还找到了similar problem,解决方案是创建一个自定义消息编码器并剥离整个安全标头,尽管这会起作用,但这是一个额外的不需要的步骤。这是使用 .Net 和 WCF 的唯一方法吗? WCF 不能处理没有内容的安全标头吗?

编辑: 澄清这个问题,是编写一个编码器来丢弃安全标头,这是使用 WCF 接收和解析具有空安全标头的 SOAP 消息的唯一方法吗?

EDIT2:添加部分配置:

    <binding name="NinjaBinding">
      <security allowSerializedSigningTokenOnReply="true" enableUnsecuredResponse="true"
      authenticationMode="UserNameOverTransport" requireDerivedKeys="false"
      securityHeaderLayout="Lax" includeTimestamp="false" allowInsecureTransport="true"
      keyEntropyMode="ClientEntropy"
      messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
      requireSecurityContextCancellation="false">
        <localServiceSettings detectReplays="false" />
        <secureConversationBootstrap _IDENTICAL_TO_ABOVE_
        </secureConversationBootstrap>
      </security>
      <textMessageEncoding />
      <httpsTransport />
    </binding>

据我所知,它的配置几乎允许一切?

【问题讨论】:

  • 您的客户端的安全配置是什么?您使用的是 WCF 还是非 WCF 服务?乳清是否包含安全标头,即使它是空的?请求中使用了什么安全性?
  • 安全配置,基本上只是 UserNameOverTransport 和 https-transport 绑定,其余的根据 ws-spec 应该无关紧要(我已经检查了每一个 App.config 设置 AFAIK)。 SOAP 的非 WCF。为什么包含标题?我不知道?但是我的客户只是在使用服务器。 req 中的安全性,与 conf 相同。问题实际上是这样的:您是否必须编写自定义消息编码器,或者您可以以某种方式配置 WCF 以在不实现编码器的情况下删除安全标头?
  • 您的意思是您使用的是安全模式 = Transport 还是 TransportWithMessageCredential?
  • 据我所知,安全模式不适用于 httpsTransport。 BasicHttpBinding 是为数不多的其中之一。还是?

标签: c# .net wcf visual-studio-2010 soap


【解决方案1】:

(现在我正在回答我自己的问题,因为我已经能够引出某种答案)

简而言之,不,您不能将 WCF“开箱即用”(即通过 *.config)与在响应中提供空安全标头的应用程序服务器一起使用。您必须实现一个编码器,将消息修改为 WCF 框架可接受的格式。

欲了解更多信息,请阅读this blog,其中包含编码器及其应用程序的相当好的演练。 This blog (another blog) 还提供了一个代码 sn-p 能够解决我的问题,即修改安全头。

我想知道为什么 MS 和 Oracle 产品永远不能和平共存:D

【讨论】:

  • 问题是 WS-Security 规范是否允许此标头为空。我没有找到明确的答案。
  • 我也没有,但没有任何内容表明它不能既为空又包含设置为 true 的 mustUnderstand 属性。
猜你喜欢
  • 2021-07-03
  • 2021-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多