wake-up-neo.com

Fügen Sie dem .net core Httpclient ein Client-Zertifikat hinzu

Ich habe mit .Net Core herumgespielt und eine API entwickelt, die Zahlungs-APIs verwendet. Für die bidirektionale SSL-Authentifizierung muss der Anforderung ein Client-Zertifikat hinzugefügt werden. Wie kann ich dies in .NET Core mit HttpClient erreichen?

Ich habe mir verschiedene Artikel angesehen und festgestellt, dass HttpClientHandler keine Option zum Hinzufügen von Clientzertifikaten bietet.

Bitte beraten

27
Krishna.N

Ich habe ein ähnliches Projekt, bei dem ich mit einem Dienst zwischen Diensten sowie zwischen Mobiltelefon und Desktop kommuniziere. 

Wir verwenden das Authenticode-Zertifikat aus der EXE-Datei, um sicherzustellen, dass unsere Binärdateien die Anforderungen erledigen. 

Auf der anfragenden Seite (für die Post vereinfacht). 

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);
    }
}

Ich verwende dann den folgenden Code für die Aktion, die die Anforderung abruft

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

Wir bieten eher eine 404 als eine 500 an, da wir diejenigen mögen, die versuchen, eine schlechte Anfrage zu erhalten, anstatt sie wissen zu lassen, dass sie auf dem richtigen Weg sind.

Ich habe eine Neuinstallation für meine Plattform (Linux Mint 17.3) mit den folgenden Schritten ausgeführt: https://www.Microsoft.com/net/core . Ich habe eine neue Konsolenanwendung erstellt, die auf das netcoreapp1.0-Framework abzielt. Ein Client-Zertifikat konnte gesendet werden. Ich habe jedoch beim Testen einen "SSL-Verbindungsfehler" (CURLE_SSL_CONNECT_ERROR 35) erhalten, obwohl ich ein gültiges Zertifikat verwendet habe. Mein Fehler könnte spezifisch für meine libcurl sein.

update: Ich habe genau das gleiche auf Windows 7 ausgeführt und es funktionierte genau so, wie es benötigt wurde.

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

Ich verwende nicht .Net für meinen Client, aber serverseitig kann es einfach über IIS konfiguriert werden, indem meine Asp.Net Core-Website hinter IIS bereitgestellt wird und IIS für HTTPS + -Clientzertifikate konfiguriert wird:

iis Client-Zertifikatseinstellung:

Dann kannst du es einfach im Code bekommen:

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

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

Es funktioniert gut für mich, aber ich benutze Curl oder Chrome als Clients, nicht .Net-Clients. Während des HTTPS-Handshakes erhält der Client eine Anforderung vom Server, ein Zertifikat bereitzustellen und an den Server zu senden. 

Wenn Sie einen .Net Core-Client verwenden, kann er keinen plattformspezifischen Code haben. Es wäre sinnvoll, wenn er sich nicht mit einem betriebssystemspezifischen Zertifikatsspeicher verbinden könnte, um ihn zu extrahieren und an den Server zu senden. Wenn Sie gegen .Net 4.5.x kompilierten, scheint das einfach zu sein:

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

Es ist wie beim Kompilieren von curl. Wenn Sie es mit dem Windows-Zertifikatsspeicher verbinden möchten, müssen Sie es mit einer bestimmten Windows-Bibliothek kompilieren.

2
Daboul

Wenn Sie die .NET Standard-Referenz für die HttpClientHandler-Klasse betrachten, können Sie feststellen, dass die Eigenschaft ClientCertificates vorhanden ist, jedoch aufgrund der Verwendung von EditorBrowsableState.Never verborgen wird. Dies hindert IntelliSense daran, es anzuzeigen, funktioniert aber weiterhin in Code, der es verwendet.

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

Kann sowohl für .NET Core 2.0 <als auch für .NET Framework 4.7.1 <verwendet werden:

var handler = new HttpClientHandler();
handler.ClientCertificates.Add(new X509Certificate2("cert.crt"));
var client = new HttpClient(handler);

https://docs.Microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler?view=netframework-4.7.1

0
Ogglas