You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET调用SOAP服务报错:无法解析签名URI '#MsgBody'

解决System.ServiceModel.Security.MessageSecurityException: Cannot resolve signature URI '#MsgBody'问题

核心原因

Java与.NET的WS-Security实现对SOAP Body的签名引用URI约定存在差异:Java服务返回的签名引用中使用#MsgBody作为Body标识,但WCF默认期望的是#Body(或无特殊前缀的Body元素ID),导致WCF无法匹配到对应签名目标,触发验证失败。

解决方案

1. 自定义MessageInspector修改响应签名引用URI

实现IClientMessageInspector,在客户端接收响应后修改XML中的签名引用URI,将#MsgBody替换为WCF可识别的#Body:

public class FixSignatureUriInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        // 将响应转为XML文档进行修改
        var doc = new XmlDocument();
        using (var reader = reply.GetReaderAtBodyContents())
        {
            doc.Load(reader);
        }

        // 定位签名引用的URI属性,替换#MsgBody为#Body
        XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
        nsMgr.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
        var referenceNodes = doc.SelectNodes("//ds:Reference/@URI", nsMgr);
        foreach (XmlNode node in referenceNodes)
        {
            if (node.Value == "#MsgBody")
            {
                node.Value = "#Body";
            }
        }

        // 重新构建Message返回
        var newReply = Message.CreateMessage(reply.Version, null, doc.CreateNavigator());
        newReply.Headers.CopyHeadersFrom(reply.Headers);
        newReply.Properties.CopyProperties(reply.Properties);
        reply = newReply;
    }
}

将该Inspector添加到客户端EndpointBehavior中:

public class FixSignatureUriBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new FixSignatureUriInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

    public void Validate(ServiceEndpoint endpoint) { }
}

创建客户端代理时绑定该Behavior:

var client = new YourSoapServiceClient();
client.Endpoint.Behaviors.Add(new FixSignatureUriBehavior());
// 调用服务方法
client.YourServiceMethod();

2. 临时关闭Body签名验证(仅测试用,不推荐)

若仅需临时验证业务逻辑,可修改配置关闭Body签名验证,但会降低安全性:
在客户端配置的<binding>节点下添加:

<security mode="Message">
  <message clientCredentialType="..." algorithmSuite="...">
    <claimTypeRequirements>
      <add claimType="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" isOptional="true" />
    </claimTypeRequirements>
    <secureConversationBootstrap />
    <!-- 跳过Body签名验证配置 -->
    <protectionLevel>Sign</protectionLevel>
    <enableUnsecuredResponse>true</enableUnsecuredResponse>
  </message>
</security>

3. 验证修改效果

修改后调用服务,通过Fiddler确认响应已被正确修改,WCF不再抛出签名验证异常,同时业务响应可正常解析。

内容的提问来源于stack exchange,提问作者dual

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:24:52