gpt4 book ai didi

c# - WCF 客户端 : First call fails, 第二次调用成功

转载 作者:行者123 更新时间:2023-12-05 07:34:15 24 4
gpt4 key购买 nike

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

当调用 REST web 服务,然后调用外部 web 服务(使用 WCF 客户端)时,在 IIS 中重新启动 REST web 服务后,WCF 客户端的第一次调用将抛出 SecurityNegotiationException。对 REST 网络服务的第二次调用,以及间接和所有后续调用都成功。

为了说明这一点,这里有一张图片: SecurityNegotiationException

这个SecurityNegotiationException如下:

System.ServiceModel.Security.SecurityNegotiationException: Could not establish secure channel for SSL/TLS with authority 'X'. ---> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.

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

我尝试过但没有解决问题的方法:

  • 在 REST 调用的同一生命周期中,在第一次调用 SOAP 网络服务后第二次(以及更多次,最多 10 次)(重复行 client.RequestInformation(parameters) )
  • 在第一次调用失败后创建一个新的 MyEndpointClient,并使用新客户端执行调用。
  • 从证书库加载证书
  • 根据 this blogpost (see tip 5) 的建议从文件加载证书
  • 使用 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 网络服务的第一次调用与下一次调用一样稳定?

最佳答案

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

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

更新:我再次遇到同样的问题,但现在是在我的开发机器上。清理证书没有帮助,所有 请求都因相同的SecurityNegotiationException 而失败。为了解决这个问题,我添加了 HTTP 100 状态代码的传递,并强制连接到 TLS 1.2:

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

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

关于c# - WCF 客户端 : First call fails, 第二次调用成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50249826/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com