I need to send data to a web api which needs a certificate to authorize. But I've no clue how I can add the certificate to the handler in .Net 4.5. This is the code:
// 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);
}
}
I searched google and found a "HttpClientHandler.ClientCertificates.Add" but that is .Net Core and not 4.5.
Is this possible with HttpClient or do I have to use the HttpWebRequest class?
UPDATE:
Related on the given answer from "Peter Bons" (thanks again) and since the using is only try-finally I changed the code to this:
// 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();
}
Unfortunately the Server response with 403 forbidden... How can I check if the authorization is working with the certificate?
UPDATE 2:
It seems like the answer to this question lies in the debugging:
I tested the password and with the wrong password for the certificate a exception happens. So I am not sure if the server is accepting the certificate but the server path is dead or the server is not accepting the certificate.
UPDATE 3:
Looking at the response object showing more information but not if the certificate caused the error.
But there is a Exception inside the content?
UPDATE 4:
Unfortunately, the server never received the certificate...
LAST UPDATE
The problem was the certificate I got from our sysadmin. Code works. Problem solved. :)
You should use the WebRequestHandler
class like in this example:
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))
{
....
}
See also this link for more background information
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With