Добавить сертификат клиента в .net core Httpclient

Я играл с .Net Core и создавал API, который использует API платежей. Там есть сертификат клиента, который необходимо добавить к запросу для двухсторонней аутентификации SSL. Как я могу достичь этого в .Net Core с помощью HttpClient?

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

Просьба сообщить

Ответы

Ответ 1

У меня есть похожий проект, в котором я общаюсь между службами, а также между мобильным и настольным службами.

Мы используем сертификат Authenticode из EXE, чтобы гарантировать, что это наши двоичные файлы, которые выполняют запросы.

С запрашивающей стороны (более упрощенной для должности).

Module m = Assembly.GetEntryAssembly().GetModules()[0];
using (var cert = m.GetSignerCertificate())
using (var cert2 = new X509Certificate2(cert))
{
   var _clientHandler = new HttpClientHandler();
   _clientHandler.ClientCertificates.Add(cert2);
   _clientHandler.ClientCertificateOptions = ClientCertificateOption.Manual;
   var myModel = new Dictionary<string, string>
   {
       { "property1","value" },
       { "property2","value" },
   };
   using (var content = new FormUrlEncodedContent(myModel))
   using (var _client = new HttpClient(_clientHandler))
   using (HttpResponseMessage response = _client.PostAsync($"{url}/{controler}/{action}", content).Result)
   {
       response.EnsureSuccessStatusCode();
       string jsonString = response.Content.ReadAsStringAsync().Result;
       var myClass = JsonConvert.DeserializeObject<MyClass>(jsonString);
    }
}

Затем я использую следующий код для действия, которое получает запрос

X509Certificate2 clientCertInRequest = Request.HttpContext.Connection.ClientCertificate;
if (!clientCertInRequest.Verify() || !AllowedCerialNumbers(clientCertInRequest.SerialNumber))
{
    Response.StatusCode = 404;
    return null;
}

Мы скорее предоставляем 404, чем 500, так как нам нравятся те, кто пытается получить неверный запрос, вместо того, чтобы сообщить им, что они "на правильном пути"

Ответ 2

Я запустил новую установку для своей платформы (Linux Mint 17.3), выполнив следующие шаги: https://www.microsoft.com/net/core. Я создал новое консольное приложение, ориентированное на структуру netcoreapp1.0, смог отправить сертификат клиента; однако во время тестирования я получил "Ошибка подключения SSL" (CURLE_SSL_CONNECT_ERROR 35), хотя я использовал действительный сертификат. Моя ошибка может быть специфичной для моего libcurl.

update. Я запускал то же самое в Windows 7, и он работал именно так, как нужно.

// using System.Net.Http;
// using System.Security.Authentication;
// using System.Security.Cryptography.X509Certificates;

var handler = new HttpClientHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.SslProtocols = SslProtocols.Tls12;
handler.ClientCertificates.Add(new X509Certificate2("cert.crt"));
var client = new HttpClient(handler);
var result = client.GetAsync("https://apitest.startssl.com").GetAwaiter().GetResult();

Ответ 3

Я не использую .Net для моего клиента, но на стороне сервера его можно настроить просто через IIS, развернув мой сайт Asp.Net Core за IIS, настроив IIS для клиентских сертификатов HTTPS +:

Настройка сертификата клиента iis:

kw8fsl.png

Затем вы можете получить его просто в коде:

        var clientCertificate = await HttpContext.Connection.GetClientCertificateAsync();

        if(clientCertificate!=null)
            return new ContentResult() { Content = clientCertificate.Subject };

Он отлично работает для меня, но я использую curl или chrome в качестве клиентов, а не .NET. Во время установления связи HTTPS клиент получает запрос от сервера для предоставления сертификата и отправки его на сервер.

Дело в том, что если вы используете .Net Core-клиент, он не может иметь код на платформе, и было бы разумно, если бы он не смог подключиться к любому хранилищу сертификатов конкретной ОС, чтобы извлечь его и отправить сервер. Если вы компилировали против .Net 4.5.x, то это кажется легким:

https://pfelix.wordpress.com/2012/12/16/using-httpclient-with-ssltls/

Как и при компиляции скручивания, если вы хотите подключиться к хранилищу сертификатов Windows, вам необходимо скомпилировать его для некоторой конкретной библиотеки Windows.

Ответ 4

Если вы посмотрите на ссылку .NET Standard для класса HttpClientHandler, то увидите, что свойство ClientCertificates существует, но скрыто из-за использования EditorBrowsableState.Never. Это препятствует тому, чтобы IntelliSense показывал это, но все еще будет работать в коде, который использует это.

[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public System.Security.Cryptography.X509Certificates.X509CertificateCollection ClientCertificates { get; }