How to send client certificate using HttpWebReques

2020-07-16 02:53发布

问题:

I have some code for pulling a client certificate from the page request. This is the code in "MyPage.aspx".

string someparam = this.Request.Params["someparam"];
if (!String.IsNullOrWhiteSpace(someparam) && this.Page.Request.ClientCertificate.IsPresent)
{
    try
    {
        X509Certificate2 x509Cert2 = new X509Certificate2(this.Page.Request.ClientCertificate.Certificate);
        //
        // Code for verifying the x509Cert2
        //
    }
    catch (Exception) { }
}

Now I want to test the code in Visual Studio in my local environment. For this I installed IISExpress to get trusted communication over https. So far so good. The problem is that my test code for sending a client certificate does not seem to work. ClientCertificate.IsPresent = false at the server.

Below is the test code. The certificate is a .pfx-file.

var request = (HttpWebRequest)WebRequest.Create("https://localhost:44300/MyPage.aspx?someparam=222");
request.Method = "POST";

X509Store store = new X509Store(StoreName.TrustedPeople, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindBySerialNumber, "XXXTHESERIALNUMBERXXX", true);
certFromStore = col[0];
store.Close();
request.ClientCertificates.Add(certFromStore);

HttpWebResponse reqWebResponse = (HttpWebResponse)request.GetResponse();
StreamReader reqResponseStream = new StreamReader(reqWebResponse.GetResponseStream(), Encoding.UTF8);

String resultHtml = reqResponseStream.ReadToEnd();

reqWebResponse.Close();
reqResponseStream.Close();

I get no errors when running the test code. The certificate is loaded correctly from the store and successfully added to request.ClientCertificates collection. But in MyPage.aspx no certificate can be pulled from the page request.

Does anyone have an idea of what I'm missing?

回答1:

You need to specify parameters in the config file for the IIS Express instance, located at
C:\Users\[username]\Documents\IISExpress\config\applicationhost.config

You should look for the security element.

The element controls whether the IIS server would accept client certificates. Setting the attribute enabled to true does this:

iisClientCertificateMappingAuthentication enabled="true"

The access element controls how to handle access. The sslFlags attribute controls how the client certificate would be treated. For some reason, the only way I've got the IIS to actually pass a certificate to the request is by setting the sslFlags to the value SslNegotiateCert as:

access sslFlags="SslNegotiateCert"