Сделайте вызов Https с помощью HttpClient
я использую HttpClient для выполнения вызовов WebApi с помощью C#. Кажется аккуратным и быстрым способом по сравнению с WebClient. Однако я застрял, делая Https звонки.
как я могу сделать ниже код Https звонки?
HttpClient httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://foobar.com/");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/xml"));
var task = httpClient.PostAsXmlAsync<DeviceRequest>(
"api/SaveData", request);
редактировать 1:
Приведенный выше код отлично подходит для выполнения http-вызовов. Но когда я меняю схему на https это не работает. Вот полученная ошибка:
базовое соединение закрыто: не удалось установить доверие
связь для безопасного канала SSL/TLS.
EDIT 2:
Изменение схемы на https: Шаг первый.
как я могу предоставить сертификат и открытый / закрытый ключ вместе с C#
запрос.
10 ответов:
если сервер поддерживает только более высокую версию TLS, например только TLS 1.2, он все равно не будет работать, если ваш клиентский компьютер не настроен на использование более высокой версии TLS по умолчанию. Чтобы преодолеть эту проблему, добавьте в свой код следующее.
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;изменение вашего примера кода, это будет
HttpClient httpClient = new HttpClient(); //specify to use TLS 1.2 as default connection System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; httpClient.BaseAddress = new Uri("https://foobar.com/"); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); var task = httpClient.PostAsXmlAsync<DeviceRequest>("api/SaveData", request);
просто укажите HTTPS в URI.
new Uri("https://foobar.com/");Foobar.com необходимо будет иметь доверенный сертификат SSL или ваши вызовы будут завершаться с ненадежной ошибкой.
изменить ответ:ClientCertificates с HttpClient
WebRequestHandler handler = new WebRequestHandler(); X509Certificate2 certificate = GetMyX509Certificate(); handler.ClientCertificates.Add(certificate); HttpClient client = new HttpClient(handler);EDIT Answer2: если сервер, к которому вы подключаетесь, отключил SSL, TLS 1.0 и 1.1, и вы все еще используете .NET framework 4.5 (или ниже), вам нужно сделать выбор
- обновление до .Net 4.6+ (поддерживает TLS 1.2 по умолчанию)
- добавьте изменения реестра, чтобы указать 4.5 для подключения через TLS1. 2 ( см.: salesforce writeup для compat и ключей для изменения или проверки IISCrypto см. Рональд Рамос ответить на комментарии)
- добавить код приложения, чтобы вручную настроить .NET для подключения через TLS1. 2 (см. Рональд Рамос ответ)
ваш код должен быть изменен следующим образом:
httpClient.BaseAddress = new Uri("https://foobar.com/");вы должны просто использовать
https:схема URI. Там есть полезная страница здесь на MSDN о безопасных HTTP-соединениях. Действительно:используйте схему https: URI
протокол HTTP определяет две схемы URI:
http: используется для незашифрованных соединений.
https: используется для безопасных соединений, которые должны быть зашифрованы. Эта опция также используются цифровые сертификаты и центры сертификации для проверки того, что сервер является тем, за кого он себя выдает.
кроме того, учтите, что соединения HTTPS используют сертификат SSL. Убедитесь, что ваше безопасное соединение имеет этот сертификат, иначе запросы не будут выполнены.
EDIT:
выше код отлично работает для выполнения http-вызовов. Но когда я меняю схема для https не работает, позвольте мне опубликовать ошибка.
Что значит не работает? Запросы не выполняются? Возникает исключение? Уточните свой вопрос.
если запросы терпят неудачу, то проблема должна быть сертификатом SSL.
чтобы устранить проблему, вы можете использовать класс
HttpWebRequestа потом его свойствоClientCertificate. Кроме того, вы можете найти здесь полезный пример о том, как сделать запрос HTTPS с помощью сертификата.примером может служить следующее (как показано на странице MSDN, связанной ранее):
//You must change the path to point to your .cer file location. X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\mycert.cer"); // Handle any certificate errors on the certificate from the server. ServicePointManager.CertificatePolicy = new CertPolicy(); // You must change the URL to point to your Web server. HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://YourServer/sample.asp"); Request.ClientCertificates.Add(Cert); Request.UserAgent = "Client Cert Sample"; Request.Method = "GET"; HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
У меня была такая же проблема при подключении к GitHub, который требует агента пользователя. Таким образом, достаточно предоставить это, а не генерировать сертификат
var client = new HttpClient(); client.BaseAddress = new Uri("https://api.github.com"); client.DefaultRequestHeaders.Add( "Authorization", "token 123456789307d8c1d138ddb0848ede028ed30567"); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add( "User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
просто указав HTTPS в URI должен сделать трюк.
httpClient.BaseAddress = new Uri("https://foobar.com/");если запрос работает с HTTP, но не работает с HTTPS, то это, безусловно, проблема сертификата. Убедитесь, что вызывающий объект доверяет издателю сертификата и что срок действия сертификата не истек. Быстрый и простой способ проверить это попробовать сделать запрос в браузере.
вы также можете проверить на сервере (если он ваш и / или если вы можете), что он настроен на обслуживание HTTPS-запросы правильно.
при подключении к
httpsЯ тоже получил эту ошибку, я добавляю эту строку передHttpClient httpClient = new HttpClient();и успешно подключиться:ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };Я знаю, что от Ответ и Еще Один Подобный Anwser и в комментарии упоминается:
это хак полезно в разработке, так что положить #if DEBUG # endif заявление вокруг него по крайней мере вы должны сделать, чтобы сделать это безопаснее и остановить это в конечном итоге в производстве
Кроме Того, Я не пробовал метод в Еще Один Ответ чтобы использовать
new X509Certificate()илиnew X509Certificate2()чтобы сделать сертификат, я не уверен, просто создать с помощьюnew()будет работать или нет.EDIT: Ссылки:
создать Самозаверяющий сертификат сервера в IIS 7
импорт и экспорт SSL сертификатов в IIS 7
рекомендации по использованию ServerCertificateValidationCallback
Я нахожу, что значение отпечатка пальца равно
x509certificate.GetCertHashString():
Я также получаю сообщение об ошибке:
базовое соединение закрыто: не удалось установить доверительные связь для безопасного канала SSL/TLS.
... с помощью Xamarin Формирует Androidнастройки приложение пытается запросить ресурсы у поставщика API, который требуется TLS 1.3.
решение состояло в том, чтобы обновить конфигурацию проекта, чтобы заменить Xamarin" управляемый " (.NET) http-клиент (который не поддерживает TLS 1.3 Как форм приложение Xamarin П2.5), и вместо того, чтобы использовать родной Android-клиент.
Это простой проект переключения в visual studio. Смотрите скриншот ниже.
- Свойства Проекта
- Android Options
- Advanced
- элемент списка
- изменить "HttpClient реализации" на "Android"
- изменить реализацию SSL/TLS на " родной TLS 1.2+"
вы можете попробовать использовать ModernHttpClient пакет Nuget: после загрузки пакета вы можете реализовать его следующим образом:
var handler = new ModernHttpClient.NativeMessageHandler() { UseProxy = true, }; ; handler.ClientCertificateOptions = ClientCertificateOption.Automatic; handler.PreAuthenticate = true; HttpClient client = new HttpClient(handler);
добавьте следующие объявления в свой класс:
public const SslProtocols _Tls12 = (SslProtocols)0x00000C00; public const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12;после:
var client = new HttpClient();и:
ServicePointManager.SecurityProtocol = Tls12; System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 /*| SecurityProtocolType.Tls */| Tls12;счастлив? :)
ошибки:
базовое соединение закрыто: не удалось установить доверительные связь для безопасного канала SSL/TLS.
Я думаю, что вам нужно принять сертификат безоговорочно со следующим кодом
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;как оппозиционные написал в своем ответе на вопрос .NET клиент подключается к ssl Web API.

Comments