C #, .Net Core Закрытый ключ аутентификации httpClient - PullRequest
6 голосов
/ 06 июня 2019

У нас проблема с другом при загрузке личного сертификата в httpHandler.
Мы используем ядро ​​.net и нам нужно разместить все приложения в облаке.
Основная цель - получить сообщение из SQS ивыполнить некоторые указанные снимки API после использования данных.
У нас проблема с сертификатом с открытым / закрытым ключом.Мы попробовали, я думаю, все возможные способы его загрузки.

    public async Task<HttpResponseMessage> VisitHttps()
    {
        // Proceed for an invalid cerficate
        ServicePointManager.ServerCertificateValidationCallback +=
        (sender, certificate, chain, sslPolicyErrors) => true;

        // Add the certificate
        var handler = new HttpClientHandler();
        var cert = GetMyCert();
        if (cert != null)
        {
            handler.ClientCertificates.Add(cert);
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
            //handler.PreAuthenticate = true;
        }
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;


        HttpClient cclient = new HttpClient(handler)
        {
            //BaseAddress = new Uri("https://someurl.com")

        };
        cclient.DefaultRequestHeaders.Accept.Clear();
        cclient.DefaultRequestHeaders.Accept.Add(new 

MediaTypeWithQualityHeaderValue("application/json"));
            return await cclient.GetAsync("https://some-url.com/ping"); }

И метод GetMyCert () выглядит следующим образом:

string currentLocation = $"{AppDomain.CurrentDomain.BaseDirectory}key-public.crt";
                //var xcert = new X509Certificate2(currentLocation, "password");

                ////var currentLocationPriv = $"{AppDomain.CurrentDomain.BaseDirectory}key-private.crt";
                ////var privcert = new X509Certificate2(currentLocationPriv, "password", X509KeyStorageFlags.EphemeralKeySet);
                //var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                //certStore.Open(OpenFlags.ReadWrite);
                //certStore.Add(xcert);
                //certStore.Close();
            //return xcert;

            X509Store store = new X509Store("My", StoreLocation.CurrentUser);
            X509Certificate2 cert;
            cert = new X509Certificate2(File.ReadAllBytes(currentLocation), "password", X509KeyStorageFlags.MachineKeySet);
            bool result = cert.Verify();
            var r2 = result;
            return cert;

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

РЕДАКТИРОВАТЬ:
Я пытался зарегистрировать это в классе запуска, но, похоже, все равно не работает.Я всегда получал пустое поле секретного ключа внутри сертификата.И hasPrivateKey помечен как ложный.

 private void CreateCert(IServiceCollection services)
    {
        string currentLocation = $"{AppDomain.CurrentDomain.BaseDirectory}key-public.crt";
        var certificate = new X509Certificate2(currentLocation, "password");
        services.AddHttpClient("TestClient", client =>
        {
            client.BaseAddress = new Uri("https://someurl.com");
        })
        .ConfigurePrimaryHttpMessageHandler(() =>
            {
            var handler = new HttpClientHandler();
            handler.ClientCertificates.Add(certificate);
            return handler;
        });
    }  

Мой тестовый код:

        [Fact]
    public async Task ShouldPong()
    {
        var testClient = new TestClient()
        {
            BaseAddress = new Uri("https://someurl.com")
        };
        var result = await testClient.GetAsync("/ping");
        result.StatusCode.Should().Be(HttpStatusCode.OK);
    }

TestClient:

public class TestClient : HttpClient
{
    public TestClient()
        :base()
    {

    }

    public TestClient(HttpMessageHandler handler)
        : base(handler)
    {

    }
}  

РЕДАКТИРОВАТЬ:
Проблема была решена при изменениифайлы .crt в файл .pfx.Поскольку API, который мы использовали, был размещен на nginx.

Ответы [ 2 ]

2 голосов
/ 12 июня 2019

Проблема была решена путем создания файла .PFX.Сервер, на котором мы работали, был размещен на nginx, который требует формат .pfx.Файлы .crt являются сертификатом PEM, который был недопустим для nginx.

0 голосов
/ 09 июня 2019

Я думаю, что вы неправильно создаете экземпляр клиента, соответственно с документом для Именованных клиентов .

Вам нужно будет получить IHttpClientFactory во время выполнения и запросить ваш именованныйклиент вроде этого:

 var client = _clientFactory.CreateClient("TestClient");

О тестировании с помощью Dependency Injection, я считаю, что это руководство Microsoft может помочь: Интеграционные тесты Asp.Net Core .Дело здесь в том, что, поскольку файл Startup.cs и Core Dependency Injector являются частью инфраструктуры, вам необходимо настроить симуляцию веб-приложения в тестовом контексте.И Microsoft предоставляет WebApplicationFactory для этого.

В этом примере демонстрируется тест с httpClient, предоставленным IHttpClientFactory в среде имитируемого веб-приложения.

...