Инфраструктура
У меня старое. NET Приложение Framework, которое я перенес со старого сервера. Он в 4.6.2 работает на Windows Server 2012 R2.
Приложение форм выполняет вызов службы WCF, работающей также на том же сервере в том же пуле приложений, а служба WCF выполняет вызов WebRequest для внешняя служба.
Для внешнего вызова требуются сертификаты для подтверждения SSL / TLS.
На старом сервере сертификаты прикреплены к запросу, но на новом сервере это не работает и нам пришлось добавить их в доверенный магазин. Это может быть важным ключом к ответу на вопрос ниже.
Проблема
Служба WCF выполняет вызов внешней службы и первый вызов (после развертывания или перезапуска приложение) всегда является ошибкой The request was aborted: Could not create SSL/TLS secure channel.
Однако ВСЕ последующие вызовы работают успешно. Это похоже на то, как если бы сертификат не загружался должным образом в профиль пользователя при первом вызове, но потом это происходит.
Это вызывает проблемы после развертывания новой версии, все первые вызовы терпят неудачу, что влияет на живой трафик c. У нас одинаковая конфигурация на 6 ящиках под балансировщиком нагрузки, и это идентичное поведение на всех 6 ящиках.
Я хочу исправить это, чтобы вызов успешно выполнялся при первом вызове.
Код
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;
}
}
То, что я пробовал
Эта статья озаглавлена «Клиент WCF: первый звонок сбой, второй вызов успешен » связано с сертификатом и очень многообещающе. Однако предложение обойти HTTP-статус 100 с помощью ServicePointManager.Expect100Continue = true;
не сработало.
Попытка установить протокол на TLS 1.2: ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Пробовал установить X509KeyStorageFlags.MachineKeySet
согласно это предложение
Из того же предложения попытался изменить идентификатор пула приложений на Network Service, LocalSystem и LocalService, ни один из которых
Другая информация
Пул приложений - это рекомендуемый идентификатор ApplicationPoolIdentity, а для параметра «Загрузить профиль пользователя» установлено значение true, в противном случае сертификаты не загружаются.
У меня заканчиваются идеи, что делать дальше, и мне нужна помощь, чтобы понять и исправить это поведение