[英]WebRequest with certificate fails on first call and succeeds all subsequent calls
Infrastructure基础设施
I have an old .NET Framework application that I migrated from an old server.我有一个从旧服务器迁移的旧 .NET 框架应用程序。 It's in 4.6.2 running on Windows Server 2012 R2.
它在 4.6.2 中运行在 Windows Server 2012 R2 上。
The forms application makes a call to a WCF service running also in the same server under the same application pool and the WCF service makes a WebRequest call to an external service. forms 应用程序调用 WCF 服务,该服务也在同一应用程序池下的同一服务器中运行,并且 WCF 服务对外部服务进行 WebRequest 调用。
The external call requires certificates for the SSL/TLS handshake.外部调用需要 SSL/TLS 握手证书。
In the old server the certificates are attached to the request, but in the new server this wasn't working and we had to add them in the trust store.在旧服务器中,证书附加到请求中,但在新服务器中,这不起作用,我们不得不将它们添加到信任库中。 This might be a important clue to the question below.
这可能是下面问题的重要线索。
The problem问题
The WCF service makes the call to the external service and the first call (after deploying or restarting the app) is always an error The request was aborted: Could not create SSL/TLS secure channel.
WCF 服务调用外部服务,第一次调用(在部署或重新启动应用程序后)总是错误
The request was aborted: Could not create SSL/TLS secure channel.
However ALL subsequent calls work successfully.但是,所有后续调用都成功运行。 It's almost as if the certificate isn't properly loaded into the user profile on the first call, but afterwards it is.
就好像证书在第一次调用时没有正确加载到用户配置文件中一样,但之后就是这样。
This is causing issues after deploying a new version, all first calls fail, which impacts live traffic.这会在部署新版本后导致问题,所有首次调用都失败,这会影响实时流量。 We have the same configuration on 6 boxes, under a load balancer and it's identical behaviour on all 6 boxes.
我们在负载均衡器下的 6 个盒子上具有相同的配置,并且在所有 6 个盒子上的行为相同。
I want to fix this so that the call succeeds on the first call.我想解决这个问题,以便在第一次通话时通话成功。
The code编码
public static Stream SendRequest(string url, string requestXml, string clientKeyBase64, string clientKeyPassword, int requestTimeout)
{
Stream os = null;
HttpWebRequest req = null;
WebResponse resp = null;
byte[] bytes;
try
{
req = (HttpWebRequest)WebRequest.Create(url);
req.Timeout = requestTimeout;
req.ContentType = "application/xml; charset=utf-8";
req.Method = "POST";
bytes = Encoding.ASCII.GetBytes(requestXml);
req.ContentLength = bytes.Length;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
if (!string.IsNullOrWhiteSpace(clientKeyBase64))
{
var cert = new X509Certificate2(Convert.FromBase64String(clientKeyBase64), clientKeyPassword);
req.ClientCertificates.Add(cert);
}
using (os = req.GetRequestStream())
{
os.Write(bytes, 0, bytes.Length);
}
using (resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
MemoryStream memStream;
memStream = new MemoryStream();
stream.CopyTo(memStream);
memStream.Seek(0, SeekOrigin.Begin); // Required to reset stream pointer at the beginning
return memStream;
}
}
}
catch (Exception ex)
{
throw ex;
}
}
Things I have tried我尝试过的事情
This article titled “WCF Client: First call fails, second call succeeds” is certificate related and extremely promising.这篇题为“WCF 客户端:第一次调用失败,第二次调用成功”的文章与证书相关,非常有前途。 However, the suggestion to bypass HTTP status 100 with
ServicePointManager.Expect100Continue = true;
但是,建议使用
ServicePointManager.Expect100Continue = true;
didn't work.没用。
Tried setting the protocol to TLS 1.2: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
尝试将协议设置为 TLS 1.2:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Tried setting X509KeyStorageFlags.MachineKeySet
as per this suggestion尝试按照此建议设置
X509KeyStorageFlags.MachineKeySet
From same suggestion, tried changing the application pool identity to Network Service, LocalSystem and LocalService none of which worked.根据相同的建议,尝试将应用程序池标识更改为 Network Service、LocalSystem 和 LocalService,但均无效。
Other info其他信息
The Application pool is the recommended identity `ApplicationPoolIdentity" and the Load User Profile setting is set to true, otherwise the certificates do not load.应用程序池是推荐的身份“ApplicationPoolIdentity”,并且“加载用户配置文件”设置设置为 true,否则不会加载证书。
I'm running out of ideas what to do next and need some help understanding and fixing this behaviour我想不出下一步该做什么,需要一些帮助来理解和修复这种行为
It seems to work now by adding these keys:现在通过添加这些键似乎可以工作:
X509KeyStorageFlags.UserKeySet |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable
Thanks谢谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.