#c# #windows-services #windows-server-2012-r2
#c# #windows-службы #windows-server-2012-r2
Вопрос:
Я знаю, что в StackOverflow и других ресурсах есть много информации об этой ошибке, но она отлично работает на моем компьютере разработчика и теперь работает в клиентской среде Windows Server 2012. Вот мой код.
public sealed class Certificates
{
private static bool subscribed = false;
private static Certificates instance = null;
private static readonly object padlock = new object();
private Certificates() { }
public static Certificates Instance
{
get
{
lock (padlock)
{
if (instance == null)
instance = new Certificates();
return instance;
}
}
}
public void GetCertificatesAutomatically()
{
if (!subscribed)
{
ServicePointManager.ServerCertificateValidationCallback =
RemoteCertificateValidationCallback;
//new RemoteCertificateValidationCallback((sender, certificate, chain, policyErrors) => { return true; });
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
ServicePointManager.MaxServicePointIdleTime = 0;
subscribed = true;
}
}
private static bool RemoteCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
// Return true if the server certificate is ok
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
bool acceptCertificate = true;
StringBuilder msg = new StringBuilder("The server could not be validate for the following reason():");
// The server did not present a certificate
if ((sslPolicyErrors amp; SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
{
msg.AppendLine(" - The server did not present a certificate.");
acceptCertificate = false;
}
else
{
// The certificate does not math the server name
if ((sslPolicyErrors amp; SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
{
msg.AppendLine(" - The certificate name does not match the authenticated name.");
acceptCertificate = false;
}
// There is som other problem with certificate
if ((sslPolicyErrors amp; SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
{
foreach (X509ChainStatus item in chain.ChainStatus)
{
if (item.Status != X509ChainStatusFlags.RevocationStatusUnknown amp;amp;
item.Status != X509ChainStatusFlags.OfflineRevocation)
{
SLICLog.Error($" - {item.StatusInformation}.");
break;
}
if (item.Status != X509ChainStatusFlags.NoError)
{
msg.AppendLine($" - {item.StatusInformation}.");
acceptCertificate = false;
}
}
}
}
// if validation failed, write log
if (!acceptCertificate)
{
acceptCertificate = true;
}
return acceptCertificate;
}
}
затем я использовал следующий код
Host = new Uri(credential.Domain);
if (Host.Scheme.Contains("https"))
Certificates.Instance.GetCertificatesAutomatically();
using (HttpWebResponse httpWebResponse = httpRequest.GetResponse() as HttpWebResponse)
using (var response = httpWebResponse.GetResponseStream())
using (var sr = new StreamReader(response))
{
token = JsonConvert.DeserializeObject<SessionInternal>(sr.ReadToEnd());
if (token != null)
{
Authorized = true;
token.Exprired = DateTime.Now.AddSeconds(Convert.ToDouble(token.expires_in));
}
}
Проблема в том, что ServerCertificateValidationCallback игнорируется на компьютере среды (я знаю это из журнала, который я добавил только для отладки).
На одном веб-сайте я прочитал, что Microsoft не разрешает игнорировать самозаверяющие сертификаты на серверных компьютерах, но не уверен. Тот же код работает на Windows10 и не работает на Windows Server 2012, а также настройки для сервера API тоже одинаковы, я имею в виду, что URL-адрес хоста и учетные данные идентичны. .NET Framework 4.7.2
ОБНОВЛЕНО:
Я не знаю почему, но работает другой сервер с самозаверяющим сертификатом, я имею в виду, что я запускаю код на сервере среды для работы с другим сервером API (это другой вид API) и вызывается делегат ServerCertificateValidationCallback. Я попытался исследовать сеть через Wireshark, и это является частью плохого соединения между клиентом / сервером, и это обычное соединение с другим сервером
Я в замешательстве, но тот же код и только другой IP серверов API и другое поведение
Ответ №1:
Я сталкиваюсь с той же проблемой — также Windows 10 работает нормально, Server 2012 R2 — нет. Я перепробовал все, начиная с .Net 4.6 и заканчивая 4.7.2 и 4.8, и это работает нормально в Win 10, но не на Win Server 2012 R2. Это с точки зрения клиента (т. Е. Win Server 2012 R2 запускает клиентское программное обеспечение, которое выходит из строя). Сайт, к которому я обращаюсь, имеет действительный сертификат GoDaddy только для TLS 1.2.