POST-запрос HttpClient с сертификатом клиента - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь позвонить стороннему API, для которого требуется сертификат клиента.Я сгенерировал сертификат клиента с помощью инструмента SSL и загрузил его на сторонний сайт.Я сгенерировал успешный POST-запрос через Postman, предоставив клиентский сертификат через их диалоги.

Заголовки:

  • X-application = (MyApplicationName)
  • Content-Type = application / x-www-form-urlencoded
  • Accept = application / json

Тело (x-www-form-urlencoded)

  • UserName = (имя пользователя)
  • Пароль = (пароль)

Когда я выполняю аналогичный запрос через .NET, я получаю код ошибки, указывающий на отсутствие сертификата.Я добавил сертификат в свое личное хранилище сертификатов и проверил, что сертификат был добавлен в обработчик веб-страниц.Кто-нибудь может подсказать, в чем может быть ошибка или как я мог диагностировать проблему?

    static async void LaunchRawHttpClient()
            {
                System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12 | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls;
                ServicePointManager.ServerCertificateValidationCallback +=
                    ValidateServerCertificate;


                string page = "https://<URL>";

                var handler = new WebRequestHandler();
                X509Certificate2 cert = GetMyCert();
                if (cert!=  null)
                {
                    handler.ClientCertificates.Add(cert);
                }
                else
                {
                    Console.WriteLine("Cert not found");
                    Console.ReadLine();
                    return;
                }


                // ... Use HttpClient.
                using (HttpClient client = new HttpClient(handler))
                {
                    client.DefaultRequestHeaders.Add("X-Application", "<applicationname>");
                    client.DefaultRequestHeaders.Add("Accept", "application/json");

                    var nvc = new List<KeyValuePair<string, string>>();
                    nvc.Add(new KeyValuePair<string, string>("username", "<username>"));
                    nvc.Add(new KeyValuePair<string, string>("password", "<password>"));

                    FormUrlEncodedContent reqContent = new FormUrlEncodedContent(nvc);
                    reqContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");


                    using (HttpResponseMessage response = await client.PostAsync(page, reqContent))
                    using (HttpContent content = response.Content)
                    {
                        // ... Read the string.
                        string result = await content.ReadAsStringAsync();

                        // ... Display the result.
                        if (result != null)
                        {
                            Console.WriteLine(result);
                        }
                    }
                }
            }

static X509Certificate2 GetMyCert()
        {
            string certThumbprint = "<thumbprint>";
            X509Certificate2 cert = null;

            var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection certCollection = store.Certificates.Find
                (X509FindType.FindByThumbprint, certThumbprint, false);

            if (certCollection.Count > 0)
                cert = certCollection[0];

            store.Close();

            return cert;
        }
public static bool ValidateServerCertificate(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
        {
            if (sslPolicyErrors == SslPolicyErrors.None)
            {
                Console.WriteLine("No SSL Errors");
                return true;
            }

            Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
            Console.ReadLine();
            return false;
        }

Я получаю сообщение «Нет ошибок SSL» x2, за которым следует отсутствующий код состояния сертификата.

Спасибозаранее Джим

1 Ответ

0 голосов
/ 11 декабря 2018

Наконец-то нашел ответ на этот вопрос - проблема в том, что файл закрытого ключа не загружался.Почтальон успешно отправил запросы, как и Керл.Curl запрашивает простоту файла ключа, и это было подсказкой.

В .NET Core - есть функция для объекта X509Certificate2, которая позволяет вам копировать его в другой объект, объединенный с файлом ключа.Мой проект находится в .NET Framework, а Core недоступен.

Я выбрал вариант использования openssl для объединения cer и файла ключа в pfx, который я загрузил в объект X509Certificate2.Сообщение Http тогда преуспело.

...