WCF客户端:第一次调用失败,第二次调用成功

2024-03-15

我有一个 REST Web 服务,它使用 WCF 客户端调用外部 SOAP Web 服务。此 REST Web 服务托管在我们测试环境中的 IIS 中。

当调用 REST Web 服务,然后调用外部 Web 服务(使用 WCF 客户端)时,在 IIS 中重新启动 REST Web 服务后,WCF 客户端的第一次调用会抛出安全协商异常。对 REST Web 服务的第二次调用以及间接调用以及所有后续调用都会成功。

To illustrate this, here's an image: SecurityNegotiationException

This 安全协商异常如下:

System.ServiceModel.Security.SecurityNegotiationException:无法使用权​​限“X”为 SSL/TLS 建立安全通道。 ---> System.Net.WebException:请求已中止:无法创建 SSL/TLS 安全通道。

端点和绑定如下(通过添加服务引用生成,稍微修改了customBinding):

<endpoint address="https://..." binding="customBinding" bindingConfiguration="MyBinding" contract="WS_..." name="MyEndpoint" />
...
<customBinding>
    <binding name="MyBinding">
      <textMessageEncoding messageVersion="Soap11" />
      <security authenticationMode="UserNameOverTransport" />
      <httpsTransport requireClientCertificate="true" />
    </binding>
</customBinding>

调用外部webservice的代码:

MyEndpointClient client = new MyEndpointClient("MyEndpoint");
client.ClientCredentials.UserName.UserName = authInfo.Username;
client.ClientCredentials.UserName.Password = authInfo.Password;
client.ClientCredentials.ClientCertificate.Certificate = authInfo.Certificate;
var result = client.requestInformation(parameters); // This fails the first time after IIS restart.

authInfo.Certificate 正在加载,如下所示:

authInfo.Certificate = new X509Certificate2(certificateBytes, certificatePassword);

更多信息:

  • 当我在本地运行 REST Web 服务时,使用 WCF 客户端调用外部服务第一次(以及所有后续调用)工作正常。
  • 我已通过添加服务引用将 SOAP Web 服务 WSDL 添加到项目中。
  • 该网络服务需要用户名和密码以及证书。必须使用WSE3.0(Windows安全扩展),我不能使用WSE2.0。
  • 在每种情况下证书都会正确加载,我已经使用 try-catch 创建了 X509Certificate2,它捕获 CryptographicException 并取消 REST-web 服务中的进一步处理(不会执行对 SOAP Web 服务的调用)。我已经验证我正在测试的证书是有效的。
  • 添加外部 SOAP Web 服务 WSDL 时,它会生成自定义绑定(因此不是我手动尝试过的 basicHttpBinding 或 WsHttpBinding)。
  • 外部 SOAP Web 服务支持 TLS 1.0、1.1 和 1.2(使用SSLLabs https://www.ssllabs.com/ssltest/analyze.html).
  • Web 服务在测试环境中以管理员权限运行。
  • 测试环境中的 IIS 在 Windows Server 2012 R2 Standard 上的版本 8.5.9600.16384 上运行

我已经尝试过但没有解决问题:

  • 在第一次调用 SOAP Web 服务后,在 REST 调用的同一生命周期中第二次(甚至更多,最多 10 次)调用 SOAP Web 服务(重复行客户端.RequestInformation(参数))
  • 在第一次失败的调用后创建新的 MyEndpointClient,并使用新客户端执行调用。
  • 从证书存储加载证书
  • 根据建议从文件加载证书这篇博文(参见提示 5) http://paulstovell.com/blog/x509certificate2
  • 使用 WsHttpBinding 或 BasicHttpBinding
  • 使用不同的认证方式在 customBinding 中的 security> 标记上。
  • Using localClientSettings reconnectTransportOnFailure="true" />在安全>标签中
  • Setting System.Net.ServicePointManager.Expect100Continue = true;
  • Setting System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;(还尝试了 TLS 1.0 和 1.1 以及TL10 | TL11 | TL12立刻)
  • Setting System.Net.ServicePointManager.ServerCertificateValidationCallback += (a,b,c,d) => true;(不是一个好主意,但值得一试)
  • Setting client.ClientCredentials.UseIdentityConfiguration = false;(也使用Web.config配置使用行为)
  • Setting client.ClientCredentials.SupportInteractive = false;(也使用Web.config配置使用行为)

有什么想法可以让 SOAP Web 服务的第一次调用与下一次调用一样稳定吗?


由于某种原因,这只发生在一台测试服务器上,而不发生在其他服务器上。 对外部 SOAP Web 服务的调用的跟踪日志显示内部函数AcquireCredentialsHandle失败并显示错误代码0X8009030D.

经过更多调查后,我发现有问题的服务器上安装了多个证书(来自外部 SOAP Web 服务)。它们似乎与对外部 SOAP Web 服务的调用发生冲突。删除这些证书后,第一次调用现在成功了!

Update:我再次遇到同样的问题,但现在是在我的开发机器上。清洁证书没有帮助,并且all请求失败,同样的情况安全协商异常。为了解决这个问题,我添加了 HTTP 100 状态代码的直通,并强制连接到 TLS 1.2:

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

请注意,我添加了这段代码before我初始化了 WCF 客户端(我的端点客户端在问题的帖子中),以确保 WCF 客户端使用这些设置。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WCF客户端:第一次调用失败,第二次调用成功 的相关文章

随机推荐