C# WCF客户端:第一次调用失败,第二次调用成功
我有一个REST Web服务,它使用WCF客户端调用外部SOAP Web服务。此REST Web服务托管在我们测试环境的IIS中 调用REST Web服务时,该服务随后调用外部Web服务(使用WCF客户端),在IIS中重新启动REST Web服务后,WCF客户端的第一次调用会引发SecurityNegotiationException。对RESTWebService的第二次调用,以及间接调用和所有后续调用成功 为了说明这一点,以下是一张图片: 此SecurityNegotiationException如下所示:C# WCF客户端:第一次调用失败,第二次调用成功,c#,wcf,wcf-binding,C#,Wcf,Wcf Binding,我有一个REST Web服务,它使用WCF客户端调用外部SOAP Web服务。此REST Web服务托管在我们测试环境的IIS中 调用REST Web服务时,该服务随后调用外部Web服务(使用WCF客户端),在IIS中重新启动REST Web服务后,WCF客户端的第一次调用会引发SecurityNegotiationException。对RESTWebService的第二次调用,以及间接调用和所有后续调用成功 为了说明这一点,以下是一张图片: 此SecurityNegotiationExcep
authInfo.Certificate = new X509Certificate2(certificateBytes, certificatePassword);
System.ServiceModel.Security.SecurityNegotiationException:无法为具有权限“X”的SSL/TLS建立安全通道。
--->System.Net.WebException:请求被中止:无法创建SSL/TLS安全通道
端点和绑定如下(通过添加服务引用生成,稍微修改了customBinding):
正在按如下方式加载authInfo.证书:
authInfo.Certificate = new X509Certificate2(certificateBytes, certificatePassword);
更多信息:
- 当我运行RESTWebService local时,使用WCF客户端调用外部服务在第一次(以及所有后续调用)时都可以正常工作
- 我已经通过添加服务引用向项目中添加了SOAP webservice WSDL
- 此Web服务需要用户名和密码以及证书。必须使用WSE3.0(Windows安全扩展),我不能使用WSE2.0
- 在每种情况下,证书都能正确加载,我使用try-catch创建X509Certificate2,它捕获加密异常并取消REST Web服务中的进一步处理(不会执行对SOAP Web服务的调用)。我已经验证了我正在测试的证书是有效的
- 添加外部SOAP webservice WSDL时,它会生成一个自定义绑定(因此不是我手动尝试的basicHttpBinding或WsHttpBinding)
- 外部SOAP Web服务支持TLS1.0、1.1和1.2(使用测试)
- webservice在测试环境中以管理员权限运行
- 测试环境中的IIS在Windows Server 2012 R2标准上的版本8.5.9600.16384上运行
- 在REST调用的同一生命周期中,在第一次调用后第二次调用SOAP Web服务(以及更多次,最多10次)(复制了line client.RequestInformation(参数))
- 在第一次调用失败后创建新的MyEndpointClient,并使用新客户端执行调用
- 从证书存储加载证书
- 根据来自的建议,从文件加载证书
- 使用WsHttpBinding或BasicHttpBinding
- 在customBinding中的security>标记上使用不同的authenticationMode
- 在security>标记中使用localClientSettings reconnectTransportOnFailure=“true”/>
- 设置System.Net.ServicePointManager.Expect100Continue=true李>
- 设置System.Net.ServicePointManager.SecurityProtocol=System.Net.SecurityProtocolType.Tls12;(同时尝试TLS 1.0和1.1以及Tls10 | Tls11 | Tls12)
- 设置System.Net.ServicePointManager.ServerCertificateValidationCallback+=(a、b、c、d)=>true;(不是个好主意,但值得一试)
- 设置client.ClientCredentials.UseIdentityConfiguration=false;(也使用Web.config配置,使用行为)
- 设置client.ClientCredentials.SupportInteractive=false;(也使用Web.config配置,使用行为)
想让对SOAP Web服务的第一次调用与下一次调用一样稳定吗?出于某种原因,这只发生在一个测试服务器上,而不是其他服务器上。 调用外部SOAP Web服务的跟踪日志显示内部函数
AcquireCredentialsHandle
失败,错误代码0X8009030D
经过进一步的调查,我发现有几个证书(来自外部SOAP web服务)安装在相关服务器上。它们似乎与对外部SOAP Web服务的调用相冲突。删除这些证书后,第一次调用现在成功
更新:我再次遇到同样的问题,但现在在我的开发机器上。清理证书没有帮助,并且所有请求都失败,出现相同的SecurityNegotiationException。为了解决这个问题,我添加了HTTP 100状态代码的传递,并强制连接到TLS 1.2:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
请注意,我在初始化WCF客户端(问题帖子中的MyEndpointClient)之前添加了此代码,以确保WCF客户端使用这些设置。tl;dr.我认为部分症状来自WCF通道属性:在发生故障后,它仍然存在故障。确保备份并创建新通道(客户端对象)。
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;