.NET 6/7中C#调用带WS-Security签名与时间戳的SOAP服务问题
.NET 6/7 实现带WS-Security签名与时间戳的SOAP请求
1. 安装必要NuGet包
首先确保项目引用以下WCF相关包:
System.ServiceModel.PrimitivesSystem.ServiceModel.HttpSystem.ServiceModel.Security
可通过NuGet命令行安装:
Install-Package System.ServiceModel.Primitives Install-Package System.ServiceModel.Http Install-Package System.ServiceModel.Security
2. 配置自定义Binding(匹配SoapUI安全设置)
创建CustomBinding来对齐SoapUI中的签名、时间戳规则:
using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Security; using System.Security.Cryptography.X509Certificates; public static Binding GetWsSecurityBinding() { // 匹配服务SOAP版本:SoapUI用SOAP 1.1则选Soap11WSAddressing10,SOAP 1.2选Soap12WSAddressing10 var textEncoding = new TextMessageEncodingBindingElement { MessageVersion = MessageVersion.Soap11WSAddressing10 }; var httpTransport = new HttpTransportBindingElement(); // 创建证书签名模式的WS-Security绑定元素 var securityElement = SecurityBindingElement.CreateMutualCertificateBindingElement( MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10); // 启用时间戳并设置有效期(和SoapUI配置一致) securityElement.IncludeTimestamp = true; securityElement.LocalClientSettings.TimestampValidityDuration = TimeSpan.FromMinutes(5); // 指定签名算法(比如SHA-256,对应SoapUI中的算法配置) securityElement.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256; return new CustomBinding(securityElement, textEncoding, httpTransport); }
3. 初始化客户端并调用服务
用自定义Binding配置客户端,加载签名证书后发起请求:
// 替换为你的服务客户端类型(通过SvcUtil或添加服务引用生成) var binding = GetWsSecurityBinding(); var serviceEndpoint = new EndpointAddress("https://your-service-endpoint-url"); using var serviceClient = new YourServiceClient(binding, serviceEndpoint); // 加载客户端签名证书(替换为你的证书指纹) serviceClient.ClientCredentials.ClientCertificate.SetCertificate( StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, "你的证书指纹"); // 测试环境可跳过服务端证书验证(生产环境禁用此设置) serviceClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; try { // 调用目标服务方法 var response = serviceClient.YourServiceMethod(); Console.WriteLine("请求成功"); } catch (FaultException ex) { Console.WriteLine($"服务返回错误:{ex.Message}"); } catch (Exception ex) { Console.WriteLine($"请求异常:{ex.Message}"); }
4. 排障要点
WSDoAllReceiver: Request does not contain required Security header错误:
多因Binding未正确添加SecurityBindingElement,或SOAP版本/安全协议与服务不匹配。建议启用WCF日志生成完整请求,和SoapUI的请求对比排查差异。- 证书权限问题:确保运行程序的账户拥有证书私钥访问权限(通过证书管理器→右键证书→管理私钥添加权限)。
- 签名算法匹配:确认
DefaultAlgorithmSuite设置和SoapUI中的签名算法完全一致(比如SoapUI用SHA-1则改为SecurityAlgorithmSuite.Basic256)。
启用WCF日志排查请求差异
在app.config中添加日志配置,生成的日志可查看完整SOAP请求:
<system.diagnostics> <sources> <source name="System.ServiceModel.MessageLogging" switchValue="Verbose"> <listeners> <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="soap-requests.svclog" /> </listeners> </source> </sources> </system.diagnostics>
内容的提问来源于stack exchange,提问作者dpater
相关产品推荐
相关产品推荐

