9

I'm attempting to access a client certificate inside my web API from an HTTP request. I'm attaching a certificate as follows:

X509Certificate2 clientCert = GetClientCertificate();   
HttpWebRequest request  = (HttpWebRequest)WebRequest.Create("https://localhost:44366/test");                        
request.KeepAlive = true;
request.Method = "GET";
request.Accept = "application/json";
request.ClientCertificates.Clear();
request.ClientCertificates.Add(clientCert);
var response = (HttpWebResponse) request.GetResponse();  

Where GetClientCertificate() accesses a locally-installed certificate. From inside my WebApi, I have the following route:

[HttpGet]
[Route("test")]
public HttpResponseMessage TestNoAuth()
{
    X509Certificate2 cert = Request.GetClientCertificate();
    return cert == null ? Request.CreateResponse(HttpStatusCode.BadRequest, "No cert") : Request.CreateResponse(HttpStatusCode.OK, "Cert attached");
}                                                              

No matter what I attempt, cert always comes back null. Am I attaching the certificate incorrectly, or trying to access it incorrectly? I've made an entirely new WebAPI with just this route for testing, to ensure there are no conflicting settings that might have been present in our development API. Any help would be greatly appreciated.

jww
  • 97,681
  • 90
  • 411
  • 885
Mason
  • 319
  • 3
  • 12
  • @Beorn if you are using IIS - go to "SSL Settings" and ensure that client certificates are "accepted" not "ignored" (default value). If it's set to ignored - certificate will be null no matter what you do. – Evk Mar 23 '17 at 07:00
  • @Evk already tried it, the certificate is still null – Beorn Mar 23 '17 at 10:32
  • 1
    @Beorn then hard to help further because I tested code provided in the question and it works fine (if you set "accepted" setting). By fine I mean it at least throws an exception if certificate is invalid, in my case. Maybe you can generate some test certificate with which you have a problem and post it somewhere? – Evk Mar 23 '17 at 10:33

2 Answers2

1

Make sure your web.config correctly sets sslFlags to SslNegotiateCert:

  <system.webServer>
    <security>
        <access sslFlags="SslNegotiateCert" />
    </security>
  </system.webServer>

Without this setting any certificate attached to the request will be ignored, see this for details.

There is a great series of articles about using client certificates in .NET by Andras Nemes. In this one it's described in detail how to setup client certificats for local test usage.

CodeFuller
  • 30,317
  • 3
  • 63
  • 79
0

You will have to set Client certificate settings in IIS. Once you do that Please make sure to add any intermediate certificates in Certificate chain to Trusted Root store. After this WebApi should be able to receive the certificate.

user1010186
  • 171
  • 1
  • 4
  • 14