c# - 使用 HttpClient 和 HttpWebRequest 进行 Https TLS1.2
问题描述
在控制台应用程序中,尝试访问使用 TLS 1.2 配置的“https”端点。
在 C# 中使用 HttpClient 时,我从端点获得成功响应
HttpClient httpClient = new HttpClient();
//specify to use TLS 1.2 as default connection
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
httpClient.BaseAddress = new Uri("HTTPSENDPOINT");
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent("POSTDATA");
var task = httpClient.PostAsync("/Token", content);
task.Wait();
Console.WriteLine(task.Result.Content.ReadAsStringAsync().Result.ToString());
但是当使用 HttpWebRequest
var request = (HttpWebRequest)WebRequest.Create("HTTPSENDPOINT/Token");
var postData = "POSTDATA";
var data = Encoding.ASCII.GetBytes(postData);
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream()) // Getting Error in GetRequestStream() method call
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
我得到以下错误
The request was aborted: Could not create SSL/TLS secure channel.
请指导我在使用 HttpWebRequest 时做错了什么?
解决方案
您需要在调用方法之前SecurityProtocol
设置属性。WebRequest.Create
更新:
让我添加一些细节来解释为什么这应该是正确的。
查看来自referencesource.microsoft.comWebRequest.Create(string)
的方法的源代码。
返回值为:
return Create(new Uri(requestUriString), false);
所以现在,让我们看一下Create(Uri, bool)
方法,它从WebRequestPrefixElement.Creator.Create(Uri)
.
Creator
是内部的一个属性WebRequestPrefixElement
,它的类型是IWebRequestCreate
. 在您的情况下,IWebRequestCreate
将是一个HttpRequestCreator
对象。
查看HttpRequestCreator.Create
方法的代码:
public WebRequest Create( Uri Uri ) {
//
// Note, DNS permissions check will not happen on WebRequest
//
return new HttpWebRequest(Uri, null);
}
最后,让我们看看那个HttpWebRequest
构造函数。你会在那里看到很长的代码,但真正重要的是这一行:
SslProtocols = (SslProtocols)ServicePointManager.SecurityProtocol;
因此该SecurityProtocol
值被分配给一个名为SslProtocols
. 所以,现在很明显,调用方法SecurityProtocol
时使用并保存到 HttpWebRequest 对象中,因此调用后更改不会更改 HttpWebRequest 对象使用的协议。Create
SecurityProtocol
Create
推荐阅读
- python - 使用 ctypes 从 C 结构构造一个 numpy 数组。值错误:'
考虑以下代码:
by_ref.h
typedef struct OutPutImage{ double *** output_img; int nb_images; i
- android - 构建 VSCode 项目时如何添加 Stacktrace 或调试选项
- python - Matplotlib:在标题和标签中迭代生成 TeX 符号
- javascript - Azure-function v2 中的相同 JSON 响应大于 V1
- c++ - 为什么我的 Rcpp 平均函数比 R 慢?
- c# - 为什么我无法打开或加载带有 GUID 或 VID / PID 的 USB 设备
- mysql - 如何对 MySQL 中两个表的数学结果求和
- java - 从多个线程访问单个数据时,如何修复 ArrayIndexOutOfBoundsException 错误?
- php - 通过第一列 id 检查第二列
- java - 如何在maven spring boot应用程序中查看lombok生成的类