postasync from example ejemplo dotnet async c# .net asp.net-core .net-core dotnet-httpclient

c# - from - Agregar certificado de cliente a.net core Httpclient



request api from c# (4)

Estaba jugando con .Net Core y estaba creando una API que utiliza API de pago. Hay un certificado de cliente que debe agregarse a la solicitud de autenticación SSL bidireccional. ¿Cómo puedo lograr esto en .Net Core utilizando HttpClient?

He mirado varios artículos y he encontrado que HttpClientHandler no proporciona ninguna opción para agregar certificados de cliente.

por favor avise


Ejecuté una instalación nueva para mi plataforma (Linux Mint 17.3) siguiendo estos pasos: https://www.microsoft.com/net/core . netcoreapp1.0 una nueva aplicación de consola orientada al framework netcoreapp1.0 , pude enviar un certificado de cliente; sin embargo, recibí un "error de conexión SSL" ( CURLE_SSL_CONNECT_ERROR 35 ) durante la prueba, aunque utilicé un certificado válido. Mi error podría ser específico a mi libcurl.

actualización : ejecuté exactamente lo mismo en Windows 7 y funcionó exactamente como fue necesario.

// 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();


No estoy usando .Net para mi cliente, pero en el lado del servidor se puede configurar simplemente a través de IIS implementando mi sitio web Asp.Net Core detrás de IIS, configurando IIS para certificados de cliente HTTPS +:

iis configuración de certificado de cliente:

Entonces puedes obtenerlo simplemente en el código:

var clientCertificate = await HttpContext.Connection.GetClientCertificateAsync(); if(clientCertificate!=null) return new ContentResult() { Content = clientCertificate.Subject };

Funciona bien para mí, pero estoy usando curl o chrome como clientes, no .Net. Durante el protocolo de enlace HTTPS, el cliente recibe una solicitud del servidor para proporcionar un certificado y enviarlo al servidor.

El problema es que, si está utilizando un cliente .Net Core, no puede tener un código específico de la plataforma y tendría sentido si no pudiera conectarse a un almacén de certificados específico del sistema operativo, para extraerlo y enviarlo al servidor. Si estaba compilando contra .Net 4.5.x, entonces parece fácil:

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

Es como cuando compila rizos, si desea poder conectarlo al almacén de certificados de Windows, debe compilarlo contra alguna biblioteca específica de Windows.


Si observa la referencia estándar de .NET para la clase HttpClientHandler , puede ver que la propiedad ClientCertificates existe, pero está oculta debido al uso de EditorBrowsableState.Never . Esto evita que IntelliSense lo muestre, pero seguirá funcionando en el código que lo usa.

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


Tengo un proyecto similar en el que me comunico entre servicios, así como entre dispositivos móviles y equipos de escritorio con un servicio.

Usamos el certificado Authenticode del EXE para asegurarnos de que nuestros binarios son los que realizan las solicitudes.

En el lado que solicita (sobre simplificado para el puesto).

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 json = new Newtonsoft.Json.JsonSerializer(); var myClass = JsonConvert.DeserializeObject<MyClass>(json); } }

Luego uso el siguiente código en la acción que recibe la solicitud

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

Preferimos proporcionar un 404 que un 500, ya que nos gustan aquellos que intentan obtener una solicitud incorrecta en lugar de informarles que están "en el camino correcto"