I have a .NET4.5 WebAPI 2 app that uses SSL Client Certificates for some custom security related checks.
When debugging the app, request.GetClientCertificate() returns null for any service call, no matter what I tried so far.
The Tested Code:
Basically, on my service's side, I have a method that goes something like this:
class CertificateChecker : ICertificateChecker
{
public bool Check(HttpRequestMessage request)
{
var cert = request.GetClientCertificate();
}
}
My unit tests with the client cert attached to the request using request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert) pass (the cert comes out exactly as expected, validations work, and so on).
However, when I use a test with an HttpClient calling the actual WebAPI app, with the break point set at the request.GetClientCertificate() line on service side, the same line returns null.
Here's what I tried:
Client Certs:
- Created a fake CA and put it into trusted CA store (tried both LocalMachine and current user).
- Created a Client Authentication (1.3.6.1.5.5.7.3.2) cert signed by that Fake CA and placed it into the Personal store (LocalMachine and Current User).
(basically, followed https://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/ and similar blogs)
On my test that calls the service using HttpClient, attached the client cert in the following ways (none of which worked):
Using
WebRequestHandlerwithClientCertificateOptionsset to Manual and the cert added to theClientCertificatescollection.using (var handler = new WebRequestHandler()) { var cert = GetTestCert(); handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ClientCertificates.Add(cert); // and so on... }Using the
HttpRequestMessage, adding the cert as a property with the key set toHttpPropertyKeys.ClientCertificateKey(this approach works when unit testing as described above).request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert);
The cert variable is set to the expected X509Certificate2 object in both cases.
Hosting:
IISExpress: Tried to run the app in IISExpress.
Edited applicationhost.config with
iisClientCertificateMappingAuthentication enabledset to "true" and the following access settings (neither worked):<access sslFlags="Ssl, SslNegotiateCert" /> <access sslFlags="SslNegotiateCert" />Local IIS Set the web app to run in IIS on my local machine
- The site in IIS is configured with an HTTPS binding using a trusted certificate.
- Web app configured to use https protocol with IIS Client Cert mapping authentication enabled.
- Tried both the access option combinations (
Ssl, SslNegotiateCertandSslNegotiateCert) (via configuration editor)
In both cases, when accessing the web api via the https url using a web browser, I get the index view of the home controller to show without issue (so, the server side cert is trusted).