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 WebRequestHandler
with ClientCertificateOptions
set to Manual and the cert added to the ClientCertificates
collection.
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 to HttpPropertyKeys.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 enabled
set 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, SslNegotiateCert
and SslNegotiateCert
) (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).
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…