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

.NET Core调用WebService报错:消息无安全头但策略要求添加

解决WebService调用错误:No Security header in message but required by policy

问题背景

调用指定WebService时触发错误:No Security header in message but required by policy,WSDL地址为https://preproduccio.ejcat.justicia.gencat.cat/cee/TTA/TTAImport?wsdl。已尝试添加PFX、.CER(二进制/Base64)格式证书均无效,该服务在Java环境可正常调用,需在.NET Core中实现,仅通过证书认证,无用户名密码。

用户实现代码:

try
{
    // la url del servicio
    string urlServicio = @"https://preproduccio.ejcat.justicia.gencat.cat/cee/TTA/TTAImport?wsdl";

    var address = new EndpointAddress(urlServicio);
    // creamos la seguridas del transporte
    var binding = new BasicHttpsBinding();
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;

    // creamos el servico que vamos a mandar
    var client = new servicioGenCATTTAImport.JwsClient(binding, address);

    // añadimos al servicio el certificado (la seguridad)
    client.ClientCredentials.ClientCertificate.SetCertificate(
        StoreLocation.CurrentUser,
        StoreName.My,
        X509FindType.FindBySerialNumber,
        conexionObject.idCertificadoEmpresa
    );

    var taulaMaestra = new servicioGenCATTTAImport.ttaconsultaTaulaMestra();

    taulaMaestra.dadesTME = new servicioGenCATTTAImport.ttaconsultaTaulaMestraDadesTME();
    taulaMaestra.dadesTME.idiomaTME = "ESP";
    taulaMaestra.dadesTME.codiTME = "TIPUS_DOCUMENT_ESCRIT";

    taulaMaestra.dadesAplicacio = new servicioGenCATTTAImport.ttaconsultaTaulaMestraDadesAplicacio();
    var bytes = File.ReadAllBytes(@"C:\Users\angel\OneDrive\Escritorio\certificados\certificadoED.pfx");
    taulaMaestra.dadesAplicacio.CDA = bytes;
    taulaMaestra.dadesAplicacio.descClient = "ANGEL RODRIGUEZ RUIZ";
    taulaMaestra.dadesAplicacio.codiClient = "50817316N";


    // llamamos al servicio
    var kk = client.consultaTME(taulaMaestra);

    return conexionObject;

}
catch (Exception ex)
{
    return conexionObject;
}

return null;

核心原因

错误表明服务要求SOAP消息携带WS-Security安全头(消息级签名/认证),而当前代码仅配置了传输层(HTTPS)的证书认证,未生成符合要求的WS-Security消息头——这也是Java环境能正常调用的原因:Java客户端通常默认配置了WS-Security策略来处理消息签名。

解决方案

1. 替换绑定为支持WS-Security的CustomBinding

使用CustomBinding配置消息级安全策略,替代原有的BasicHttpsBinding:

string urlServicio = @"https://preproduccio.ejcat.justicia.gencat.cat/cee/TTA/TTAImport?wsdl";
var address = new EndpointAddress(urlServicio);

// 创建自定义绑定
var binding = new CustomBinding();

// 添加文本消息编码(匹配WSDL的SOAP版本,通常为1.1)
var textEncoding = new TextMessageEncodingBindingElement
{
    MessageVersion = MessageVersion.Soap11WSAddressing10
};
binding.Elements.Add(textEncoding);

// 添加HTTPS传输层配置
var httpsTransport = new HttpsTransportBindingElement
{
    RequireClientCertificate = true
};
binding.Elements.Add(httpsTransport);

// 配置WS-Security消息级签名
var securityElement = SecurityBindingElement.CreateMutualCertificateBindingElement(
    MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);

// 设置客户端证书用于消息签名
securityElement.EndpointSupportingTokenParameters.Signed.Add(new X509SecurityTokenParameters
{
    InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient,
    ReferenceStyle = SecurityTokenReferenceStyle.IssuerSerial
});

// 将安全元素插入绑定的最前面
binding.Elements.Insert(0, securityElement);

// 创建客户端
var client = new servicioGenCATTTAImport.JwsClient(binding, address);

2. 确保证书包含私钥并正确加载

如果从证书存储加载有问题,直接从PFX文件加载并确保私钥可用:

// 加载PFX证书(替换为你的PFX路径和密码)
var pfxPath = @"C:\Users\angel\OneDrive\Escritorio\certificados\certificadoED.pfx";
var pfxPassword = "你的PFX密码";
var cert = new X509Certificate2(pfxPath, pfxPassword, 
    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);

// 给客户端配置证书
client.ClientCredentials.ClientCertificate.Certificate = cert;

3. 验证安全头生成(可选)

开启SOAP消息日志,确认安全头是否正确生成:
在appsettings.json添加配置:

{
  "System.ServiceModel.MessageLogging": {
    "LogEntireMessage": true,
    "LogMessagesAtServiceLevel": true,
    "LogMessagesAtTransportLevel": true
  }
}

在Program.cs中启用日志:

var builder = WebApplication.CreateBuilder(args);

// 配置WCF消息日志
var messageLoggingConfig = builder.Configuration.GetSection("System.ServiceModel.MessageLogging");
if (messageLoggingConfig.Exists())
{
    var loggingSettings = messageLoggingConfig.Get<Microsoft.ServiceModel.Logging.MessageLoggingSettings>();
    Microsoft.ServiceModel.Logging.MessageLoggingSettings.Instance.ApplySettings(loggingSettings);
}

// 其他服务配置...

var app = builder.Build();

4. 匹配WSDL的安全策略

查看WSDL中的<wsp:Policy>节点,确认具体的安全约束(如是否要求时间戳、签名算法等),调整SecurityBindingElement的配置:

// 示例:添加时间戳要求
securityElement.IncludeTimestamp = true;
// 示例:设置签名加密顺序
securityElement.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;

内容的提问来源于stack exchange,提问作者Angel-ito

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 22:42:48