Make Https call using HttpClient
我一直在使用
如何进行以下代码进行
1 2 3 4 5 6 7 8 | HttpClient httpClient = new HttpClient(); httpClient.BaseAddress = new Uri("https://foobar.com/"); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/xml")); var task = httpClient.PostAsXmlAsync<DeviceRequest>( "api/SaveData", request); |
编辑1:
上面的代码可以很好地进行http调用。 但是,当我将方案更改为https时,它不起作用。 这是获得的错误:
The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel.
编辑2:
将方案更改为https是:第一步。
How do I supply certificate & public / private key along with C#
request.
如果服务器仅支持更高的TLS版本(例如仅TLS 1.2),则除非您的客户端PC默认配置为使用更高的TLS版本,否则服务器仍将失败。要解决此问题,请在代码中添加以下内容。
1 | System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; |
修改您的示例代码,它将是
1 2 3 4 5 6 7 8 9 10 | HttpClient httpClient = new HttpClient(); //specify to use TLS 1.2 as default connection System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; httpClient.BaseAddress = new Uri("https://foobar.com/"); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); var task = httpClient.PostAsXmlAsync<DeviceRequest>("api/SaveData", request); |
只需在URI中指定HTTPS。
1 |
Foobar.com将需要具有受信任的SSL证书,否则您的呼叫将因不受信任的错误而失败。
编辑答案:ClientCertificates与HttpClient
1 2 3 4 |
编辑答案2:如果要连接的服务器已禁用SSL,TLS 1.0和1.1,并且您仍在运行.NET Framework 4.5(或更低版本),则需要做出选择
您的代码应通过以下方式修改:
1 |
您只需使用
MSDN上有一个关于安全HTTP连接的有用页面。确实:
Use the https: URI scheme
The HTTP Protocol defines two URI schemes:
http : Used for unencrypted connections.
https : Used for secure connections that should be encrypted. This option also uses digital certificates and certificate authorities to verify that the server is who it claims to be.
此外,请考虑HTTPS连接使用SSL证书。确保您的安全连接具有此证书,否则请求将失败。
编辑:
Above code works fine for making http calls. But when I change the
scheme to https it does not work, let me post the error.
这是什么意思?请求失败?抛出异常了吗?澄清您的问题。
如果请求失败,则问题应该是SSL证书。
要解决此问题,可以使用类
此外,您可以在此处找到有关如何使用证书发出HTTPS请求的有用示例。
以下是一个示例(如之前链接的MSDN页面所示):
1 2 3 4 5 6 7 8 9 10 | //You must change the path to point to your .cer file location. X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\\mycert.cer"); // Handle any certificate errors on the certificate from the server. ServicePointManager.CertificatePolicy = new CertPolicy(); // You must change the URL to point to your Web server. HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://YourServer/sample.asp"); Request.ClientCertificates.Add(Cert); Request.UserAgent ="Client Cert Sample"; Request.Method ="GET"; HttpWebResponse Response = (HttpWebResponse)Request.GetResponse(); |
当连接到
1 | ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; |
我从"这个答案"和"另一个类似的答案"知道这一点,并且评论中提到:
This is a hack useful in development so putting a #if DEBUG #endif statement around it is the least you should do to make this safer and stop this ending up in production
此外,我没有尝试使用"
编辑:一些参考:
在IIS 7中创建自签名服务器证书
在IIS 7中导入和导出SSL证书
将.pfx转换为.cer
使用ServerCertificateValidationCallback的最佳做法
我发现Thumbprint的值等于
检索证书的指纹
连接到需要用户代理的GitHub时,我遇到了同样的问题。因此,提供此证书而不是生成证书就足够了
1 2 3 4 5 6 7 8 9 10 11 | var client = new HttpClient(); client.BaseAddress = new Uri("https://api.github.com"); client.DefaultRequestHeaders.Add( "Authorization", "token 123456789307d8c1d138ddb0848ede028ed30567"); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add( "User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); |
仅在URI中指定HTTPS就可以解决问题。
1 |
如果请求适用于HTTP,但不能适用于HTTPS,则很可能是证书问题。确保调用方信任证书颁发者,并且证书未过期。一种快速简便的检查方法是尝试在浏览器中进行查询。
您可能还需要检查服务器(如果是您的服务器和/或(如果可以的话))已将其设置为正确处理HTTPS请求。
我也收到错误:
The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel.
...并以Xamarin Forms Android为目标的应用程序尝试从需要TLS 1.3的API提供程序请求资源。
解决方案是更新项目配置,以换出Xamarin"托管"(.NET)http客户端(该客户端自Xamarin Forms v2.5起不支持TLS 1.3),而改用android native客户端。
这是Visual Studio中的一个简单项目切换。请参见下面的屏幕截图。
- 项目属性
- Android选项
- 高级
- 项目清单
- 将" HttpClient实现"更改为" Android"
- 将SSL / TLS实施更改为"本机TLS 1.2+"
在
1 2 3 4 5 6 |
这样就启用了最新的TLS版本。
请注意,默认值
将以下声明添加到您的班级:
1 2 | public const SslProtocols _Tls12 = (SslProtocols)0x00000C00; public const SecurityProtocolType Tls12 = (SecurityProtocolType)_Tls12; |
后:
1 |
和:
1 2 | ServicePointManager.SecurityProtocol = Tls12; System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 /*| SecurityProtocolType.Tls */| Tls12; |
快乐? :)
我同意felickz,但我也想添加一个示例来阐明c#中的用法。我在Windows服务中使用SSL,如下所示。
1 2 3 4 5 6 7 8 9 10 11 | var certificatePath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory,"bin"); gateway = new GatewayService(); gateway.PreAuthenticate = true; X509Certificate2 cert = new X509Certificate2(certificatePath + @"\Attached\my_certificate.pfx","certificate_password"); gateway.ClientCertificates.Add(cert); ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; gateway.UserAgent = Guid.NewGuid().ToString(); gateway.Timeout = int.MaxValue; |
如果要在Web应用程序中使用它,我只是在代理端更改实现,如下所示:
1 | public partial class GatewayService : System.Web.Services.Protocols.SoapHttpClientProtocol // to => Microsoft.Web.Services2.WebServicesClientProtocol |
我遇到了这个问题,就我而言,解决方案非常简单:用管理员权限打开Visual Studio。我尝试了上述所有解决方案,但直到执行此操作,它才起作用。希望它可以节省一些宝贵的时间。
您可以尝试使用ModernHttpClient Nuget软件包:下载该软件包后,可以像这样实现它:
1 2 3 4 5 6 7 8 9 |
对于错误:
The underlying connection was closed: Could not establish trust
relationship for the SSL/TLS secure channel.
我认为您需要使用以下代码无条件接受证书
1 2 | ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; |
正如Oppositional在他对.NET客户端连接到ssl Web API的问题的回答中所写。