2016-10-13 53 views
18

我在使用.Net Core並構建一個利用支付API的API。有一個客戶端證書需要添加到雙向SSL身份驗證請求中。 如何使用HttpClient在.Net Core中實現此目標?將客戶端證書添加到.net核心Httpclient

我看過各種文章,發現HttpClientHandler沒有提供任何選項來添加客戶端證書。

請告知我沒有使用的.Net爲我的客戶

回答

18

我按照以下步驟爲我的平臺(Linux Mint 17.3)執行全新安裝:https://www.microsoft.com/net/core。我創建了一個針對netcoreapp1.0框架的新控制檯應用程序,能夠提交客戶端證書;然而,即使我使用了有效的證書,我在測試時也收到了「SSL連接錯誤」(CURLE_SSL_CONNECT_ERROR 35)。我的錯誤可能是特定於我的libcurl。

更新:我在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(); 
+0

woha它的工作夥伴,非常感謝你花時間來幫助我。這些日子我都休假了。 –

+0

我很好奇。你有沒有得到這個在Linux機器或Windows上工作? – Steven

+0

我得到它在Windows(10)和Linux(薄荷17.3,18和18.1)工作。當我嘗試使用沒有私鑰的證書時,我確實收到了「SSL連接錯誤」(CURLE_SSL_CONNECT_ERROR 35)。 – yfisaqt

2

,但服務器端它可以簡單地通過IIS配置,部署我的身後IIS Asp.Net核心網,配置IIS用於HTTPS +客戶端證書:

IIS客戶端證書設置:

然後,你可以把它簡單地在代碼:

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

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

它對我來說很好,但我使用捲曲或鉻作爲客戶端,而不是.Net。在HTTPS握手期間,客戶端從服務器獲取請求以提供證書並將其發送到服務器。

問題是,如果您使用的是.Net Core客戶端,它不能具有特定於平臺的代碼,並且如果它無法將其自身連接到任何操作系統特定的證書存儲庫,將其解壓併發送到服務器。如果你對淨4.5.x編譯那麼它似乎很容易:

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

這是當你編譯捲曲,如果你希望能夠將它連接到Windows證書存儲區一樣,你必須編譯它針對一些特定的Windows庫。

+0

感謝您抽出時間回答,但我正在使用此爲asp.net核心。上面的代碼適合我。 –

0

我有一個類似的項目,我可以在服務之間以及在移動和桌面之間使用服務進行通信。

我們使用EXE的Authenticode證書來確保它是我們執行請求的二進制文件。

在請求方(超過簡化的職位)。

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

然後我用對獲取請求的動作將以下代碼

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

我們寧願提供404比500,因爲我們喜歡那些試圖網址來得到一個壞的請求,而不是讓他們知道他們在「正確的軌道上」