【问题标题】:C#, How can I add the certificate to the HttpClientHandler?C#,如何将证书添加到 HttpClientHandler?
【发布时间】:2017-10-30 16:26:57
【问题描述】:

我需要将数据发送到需要证书授权的 web api。但我不知道如何将证书添加到 .Net 4.5 中的处理程序。这是代码:

// Import the certificate
X509Certificate2Collection certificates = new X509Certificate2Collection();
certificates.Import(pathToCertificate, password, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;

using (var handler = new HttpClientHandler() { })
{
    using (var client = new HttpClient(handler))
    {
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


        // Build the JSON
        string json = JsonConvert.SerializeObject(userData, Formatting.Indented);
        Console.WriteLine(json);

        var httpContent = new StringContent(json, Encoding.UTF8, "application/json");

        var processResult = await client.PostAsync(uriToServer, httpContent);
        var responseBody = processResult.Content.ReadAsStringAsync().Result;

        Console.WriteLine(responseBody);
        //return JsonConvert.DeserializeObject<string>(responseBody);
    }
}

我搜索了谷歌并找到了一个“HttpClientHandler.ClientCertificates.Add”,但那是 .Net Core 而不是 4.5。

这可以通过 HttpClient 实现还是我必须使用 HttpWebRequest 类?

更新:

与“Peter Bons”给出的答案相关(再次感谢),并且由于使用只是尝试 - 最后我将代码更改为:

// Create an WebRequestHandler instance
var handler = new WebRequestHandler();

// Add the certificate
var certFile = Path.Combine(pathToWorkingDirectory, "SERVER.PFX");
handler.ClientCertificates.Add(new X509Certificate2(certFile, "password"));

var client = new HttpClient(handler);
try
{
    //client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    var httpContent = new StringContent(json, Encoding.UTF8, "application/json");

    //var processResult = await client.GetAsync("https://server/login");
    var processResult = await client.PostAsync("https://server/p/m", httpContent);
    var responseBody = processResult.Content.ReadAsStringAsync().Result;

    Console.WriteLine(responseBody);
}
catch (Exception e)
{
    Console.WriteLine($"ERROR: {e}");
}
finally
{
    client.Dispose();
}

不幸的是,服务器响应 403 被禁止... 如何检查授权是否与证书一起使用?

更新 2:

似乎这个问题的答案在于调试:

我测试了密码,但使用错误的证书密码会发生异常。所以我不确定服务器是否正在接受证书但服务器路径已死或服务器不接受证书。

更新 3:

查看显示更多信息的响应对象,但不是证书是否导致错误。

但是内容里面有异常?

更新 4:

很遗憾,服务器从来没有收到过证书……

最后更新

问题是我从我们的系统管理员那里得到的证书。代码有效。问题解决了。 :)

【问题讨论】:

    标签: c# ssl


    【解决方案1】:

    你应该使用WebRequestHandler 这个例子中的类:

    var handler = new WebRequestHandler();
    
    var certFile = Path.Combine(@"d:\temp\", "cert.pfx");
    handler.ClientCertificates.Add(new X509Certificate2(certFile, "password"));
    
    using (var client = new HttpClient(handler))
    {
        ....
    }
    

    有关更多背景信息,另请参阅this link

    【讨论】:

    • 这太棒了!感谢你的回答。 :-) 我会阅读背景信息并提供反馈。
    • 不幸的是,我们的系统管理员告诉我服务器永远不会收到证书。也许您有时间查看我的更新并检查我做错了什么?
    • @user3772108 我 100% 确定我的答案中的代码是正确的,但请注意 Web 服务器可能需要其他信息。因此,您应该与您的系统管理员核实服务器是否已正确配置。见technet.microsoft.com/en-us/library/…。不幸的是,这超出了问题的范围,很难对此提供帮助。正如您在调试客户端证书时所看到的那样,这部分可以正常工作。
    • 好的,那么调试(截图)是正确的并且客户端确实发送了带有证书的请求(POST)?再次感谢您的回答。我会和我们的系统管理员核实一下。
    • 你是对的!是证书!难以置信...再次感谢您的大力帮助! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 2014-06-30
    • 2011-01-05
    • 2013-04-10
    • 2013-05-09
    相关资源
    最近更新 更多