Make Https Call Using Httpclient

Make Https call using HttpClient

If the server only supports higher TLS version like TLS 1.2 only, it will still fail unless your client PC is configured to use higher TLS version by default. To overcome this problem, add the following in your code:

System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

Modifying your code example, it would be

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

Make HTTPS call through HttpClient with client certificate that does not have access to private key

Is it possible to send client certificate without (access to) private key in HTTPs request (e.g. by using HttpClient)?

You can send it as content, sure; but you cannot use it as a client certificate without the private key. It would be like logging in to a system by just asserting a username.

The technical reason is that whenever certificates are sent in TLS there's also a required signature that has to be sent to prove that the private key is held by the sender. If the signature doesn't validate, then the recipient terminates the session.

Posting a dictionary as data to HTTPS server in C# using HTTPClient

Try using this approach, it works with the server I am sending data to.

var content = new StringContent("{some:json}");
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

client.DefaultRequestHeaders.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;"));

HttpResponseMessage response = await client.PostAsync("https://SERVER_ADRESS", content);

I suspect the request header is the reason, and send StringContent instead of FormUrlEncodedContent

HTTPS request fails using HttpClient

According to this SO post, you must enable TLS1.2 with ServicePointManager.

System.Net.ServicePointManager.SecurityProtocol |=
SecurityProtocolType.Tls12 |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls; // comparable to modern browsers

Also noteworthy, the MSDN documentation for ServicePointManager.SecurityProtocols property makes this statement:

The .NET Framework 4.6 includes a new security feature that blocks
insecure cipher and hashing algorithms for connections.

which suggests that some form of SHA1 block might be in place.

EDIT 16 Sep 2020

I changed from the = assignment operator to the |= operator so that requests to any other legacy sites which still require SSL will continue to work.

Using HttpClient & HttpWebRequest for Https TLS1.2

You need to set the SecurityProtocol property before calling WebRequest.Create method.

Update:

Let me add some details that explain why this should be correct.

Having a look at the source code of WebRequest.Create(string) method from referencesource.microsoft.com.

The return value is:

return Create(new Uri(requestUriString), false);

so now, Let's take a look at Create(Uri, bool) method, it returns some object from WebRequestPrefixElement.Creator.Create(Uri).

Creator is a property inside of WebRequestPrefixElement and it's of type IWebRequestCreate.
In your case, IWebRequestCreate will be an HttpRequestCreator object.

Looking at the code of HttpRequestCreator.Create method:

public WebRequest Create( Uri Uri ) {
//
// Note, DNS permissions check will not happen on WebRequest
//
return new HttpWebRequest(Uri, null);
}

Finally, Let's look at that HttpWebRequest constructor.
You'll see a long code there, but really what is important is this line:

SslProtocols = (SslProtocols)ServicePointManager.SecurityProtocol;

so the SecurityProtocol value is assigned to a property called SslProtocols.
So, it's obvious now that SecurityProtocol is used and kind of saved to the HttpWebRequest object when you call Create method, so changing SecurityProtocol after calling Create will not change the protocol used by the HttpWebRequest object.



Related Topics



Leave a reply



Submit