使用HttpClient进行Https调用
我一直在使用HttpClient
使用C#进行WebApi调用。 与WebClient
相比,似乎整洁快捷。 不过,当我打开Https
调用时,
我怎样才能使下面的代码,使Https
调用?
HttpClient httpClient = new HttpClient(); httpClient.BaseAddress = new Uri("http://foobar.com/"); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/xml")); var task = httpClient.PostAsXmlAsync<DeviceRequest>( "api/SaveData", request);
编辑1:上面的代码工作正常进行http调用。 但是,当我改变scheme到https它不起作用。 这是得到的错误:
底层连接已closures:无法build立SSL / TLS安全通道的信任关系。
编辑2:改变scheme为https是:第一步。
如何随C#请求一起提供证书和公钥/私钥。
只需在URI中指定HTTPS即可。
new Uri("https://foobar.com/");
Foobar.com将需要有一个可信的SSL证书或您的电话将失败,不可信的错误。
编辑答案: 与HttpClient ClientCertificates
WebRequestHandler handler = new WebRequestHandler(); X509Certificate2 certificate = GetMyX509Certificate(); handler.ClientCertificates.Add(certificate); HttpClient client = new HttpClient(handler);
编辑回答2:如果您连接到的服务器已禁用SSL,TLS 1.0和1.1,您仍然运行的.NET框架4.5(或以下),您需要作出select
- 升级到.Net 4.6+( 默认支持TLS 1.2 )
- 添加registry更改以指示4.5通过TLS1.2进行连接(请参阅:用于compat的salesforce writeup和要更改的键或检出IISCrypto请参阅Ronald Ramos answer comments )
- 添加应用程序代码以手动configuration.NET以通过TLS1.2进行连接(请参阅Ronald Ramos的答案 )
如果服务器仅支持TLS 1.2等更高版本的TLS版本,则除非您的客户端PC默认configuration为使用更高的TLS版本,否则它将仍然失败。 要解决这个问题,请在代码中添加以下内容。
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
修改你的示例代码,这将是
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);
你的代码应该这样修改:
httpClient.BaseAddress = new Uri("https://foobar.com/");
您只需使用https:
URIscheme。 在MSDN上有一个关于安全HTTP连接的有用的页面。 确实:
使用https:URIscheme
HTTP协议定义了两个URIscheme:
http:用于未encryption的连接。
https:用于应该encryption的安全连接。 此选项也使用数字证书和证书颁发机构来validation服务器是谁声称。
此外,请考虑HTTPS连接使用SSL证书。 确保您的安全连接具有此证书,否则请求将失败。
编辑:
上面的代码可以很好地进行http调用。 但是当我改变scheme到https不起作用,让我发布错误。
这是什么意思不起作用? 请求失败? 抛出exception? 澄清你的问题。
如果请求失败,那么问题应该是SSL证书。
要解决这个问题,你可以使用HttpWebRequest
类,然后使用它的属性ClientCertificate
。 此外,您可以在这里find有关如何使用证书进行HTTPS请求的有用示例。
下面是一个例子(如之前链接的MSDN页面所示):
//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();
当连接到需要用户代理的GitHub时,我遇到了同样的问题。 因此,提供这个而不是生成一个证书就足够了
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就可以了。
httpClient.BaseAddress = new Uri("https://foobar.com/");
如果请求与HTTP一起工作,但HTTPS失败,那么这肯定是一个证书问题 。 确保调用者信任证书颁发者并且证书没有过期。 一个快速而简单的方法来检查,即尝试在浏览器中进行查询。
您也可能需要检查服务器(如果是您的和/或可以的话)是否设置为正确提供HTTPS请求。
你可以尝试使用ModernHttpClient的 Nuget包:下载包后,你可以像这样实现它:
var handler = new ModernHttpClient.NativeMessageHandler() { UseProxy = true, }; ; handler.ClientCertificateOptions = ClientCertificateOption.Automatic; handler.PreAuthenticate = true; HttpClient client = new HttpClient(handler);
当连接到https
我也得到这个错误,我添加此行之前HttpClient httpClient = new HttpClient();
并成功连接:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
我从“ 这个答案”和“ 另一个类似的 答案”中得到了答案 ,评论中提到:
这是一个有用的开发,所以#if DEBUG #endif声明是最不重要的,你应该做的更安全,并停止在生产结束
此外,我没有尝试这种方法, 另一个答案使用new X509Certificate()
或new X509Certificate2()
来作出一个证书,我不确定简单地创buildnew()
将工作与否。
- Web Api的Xml文档如何包含主项目之外的文档?
- 压缩HTTP GET响应
- 在ASP.net MVC 4 WebApi中嵌套的资源
- 使用JWT在Asp.net Web API上实现身份validation
- 什么是网站API的黄金标准? Twitter,Flickr,Facebook等
- 使用自定义用户数据库的Web API令牌authentication
- 需要将asp.net webapi 2请求和响应正文logging到数据库中
- 在Asp.Net的/ bin文件夹中,Roslyn“需要”什么/为什么?
- 点字符“。” 在MVC Web API 2中用于请求如api / people / STAFF.45287