.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
相关产品推荐
相关产品推荐

