Сбой HttpWebrequest с внутренним исключением. Проверка подлинности завершилась неудачно, поскольку удаленная сторона закрыла транспортный поток.

Используя C#, .Net 4.5, я пытаюсь отправить веб-запрос через HttpWebRequest на удаленный сервер. Пожалуйста, смотрите код ниже. Я испробовал большинство решений, предложенных на некоторых форумах, но всегда сталкивался с одной и той же ошибкой. Пожалуйста, смотрите трассировку стека ниже. Ошибка вызывается при вызове метода request.GetReponse().

Дополнительная информация, в основном, я пытаюсь вызвать функцию reloadSslCertificate компонента vCenter vmware, установленного на удаленном сервере. В настоящее время ошибка происходит только в vCenter 5.5. Он отлично работает в версиях 5.1 и ниже.

        var uri = String.Format("https://{0}/some_url", serverName);
        var request = (HttpWebRequest)WebRequest.Create(uri);
        request.KeepAlive = true;
        request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8");
        request.Credentials = credential;
        request.CookieContainer = cookieContainer;


        var response = request.GetResponse();

Исключение: System.Net.WebException: базовое соединение было закрыто: при отправке произошла непредвиденная ошибка. ---> System.IO.IOException: аутентификация не удалась, потому что удаленная сторона закрыла транспортный поток. в System.Net.Security.SslState.StartReadFrame(буфер Byte[], int32 readBytes, AsyncProtocolRequest asyncRequest) в System.Net.Security.SslState.StartReceiveBlob(буфер Byte[], AsyncProtocolRequest asyncReSec.CheckCompletionBeforeNextReceive(сообщение ProtocolToken, AsyncProtocolRequest asyncRequest) в System.Net.Security.SslState.StartSendBlob(Byte[] входящий, число Int32, AsyncProtocolRequest asyncRequest) в System.Net.Security. asyncRequest) в System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) в System.Net.TlsStream.CallProcessAuthentication(состояние объекта) в System.Threading.ExecutionContext.RunInternal (состояние объекта Conject, обратный_брос вызова объекта) System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта, логическое значение preserveSyncCtx) в System.Threading.ExecutionContext.Run(ExecutionContext executeContext, обратный вызов ContextCallback, состояние объекта) в System.Net.TlsStream.ProcessAuthentication(результат LazyAsyncResult) в System.Net.TlsStream.Write(байт [], смещение Int32, Int32 size) в System.Net.PooledStream.Write(буфер Byte[], смещение Int32, размер Int32) в System.Net.ConnectStream.WriteHeaders(логический асинхронный) --- конец трассировки стека внутренних исключений --- в System.Net.HttpWebRequest.GetResponse()

Заранее спасибо.

3 ответа

Решение

Я просто хочу поделиться, что эта проблема уже решена.

Я просто изменил часть кода, в которой я устанавливаю протокол безопасности, прежде чем отправлять веб-запрос.

От:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

Для того, чтобы:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;

Как оказалось, vCenter 5.5 использует TLS в качестве протокола SSL в своей конфигурации. Я надеюсь, что люди могут найти это полезным, когда они сталкиваются с этой же проблемой.

Мы столкнулись с тем же исключением. В нашем случае ответ был невероятно похож на ответ @Dennis Laping. Другая команда настроила сервис, который мы пытались использовать в балансировщике нагрузки Rancher, который по умолчанию не допускал TLS 1.0 или SSL3. Так случилось, что текущее значение по умолчанию для SecurityProtocol (без его настройки) в.NET допускает только TLS 1.0 или SSL3.

Как только мы установили SecurityProtocol следующим образом, все заработало нормально:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

При этом в документации по SecurityProtocol говорится, что:

Ваш код никогда не должен явно зависеть от использования определенного уровня защиты или от предположения, что данный уровень безопасности используется по умолчанию. Если ваше приложение зависит от использования определенного уровня безопасности, вы должны явно указать этот уровень, а затем проверить, действительно ли оно используется на установленном соединении. Кроме того, ваш код должен быть спроектирован так, чтобы он был устойчивым к изменениям поддерживаемых протоколов, поскольку такие изменения часто вносятся без предварительного уведомления, чтобы смягчить возникающие угрозы.

Мы будем переоценивать то, что является лучшим решением для нашей ситуации с протоколом, но сейчас я надеюсь, что это поможет кому-то еще.

Посмотрите эту ссылку, у меня это сработало: как сделать HTTPS с TcpClient, как это делает HttpWebRequest?

Dim trust_all_certificates As New CertificateOverride
ServicePointManager.ServerCertificateValidationCallback = AddressOf trust_all_certificates.RemoteCertificateValidationCallback
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3

Public Class CertificateOverride

    Public Function RemoteCertificateValidationCallback(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean

        'CertEXPIRED = 2148204801
        'CertVALIDITYPERIODNESTING = 2148204802
        'CertPATHLENCONST = 2148204804
        'CertROLE = 2148204803
        'CertCRITICAL = 2148204805
        'CertPURPOSE = 2148204806
        'CertISSUERCHAINING = 2148204807
        'CertMALFORMED = 2148204808
        'CertUNTRUSTEDROOT = 2148204809
        'CertCHAINING = 2148204810
        'CertREVOKED = 2148204812
        'CertUNTRUSTEDTESTROOT = 2148204813
        'CertREVOCATION_FAILURE = 2148204814
        'CertCN_NO_MATCH = 2148204815
        'CertWRONG_USAGE = 2148204816
        'CertUNTRUSTEDCA = 2148204818

        Return True

    End Function

End Class

PS

Я вставил эту строку кода перед тем, чтобы убедиться, что сертификат со стороны сервера принят: ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3

Другие вопросы по тегам