Refer to the document
http://southworks.com/blog/2014/06/16/enabling-ssl-client-certificates-in-asp-net-web-api/
The first step is to create a Trusted Root Certification Authority
makecert.exe -n "CN=Development CA" -r -sv DevelopmentCA.pvk DevelopmentCA.cer
And import the certificate into certificate management, pay special attention to it must be "certificate - local computer", not the current user
The second step is to use the root certificate just created to create the pfx format of the certificate. The first command creates the certificate, and the second command will convert it to pfx format and include the private key. "123456" is the private key password
makecert.exe -pe -n "CN=localhost" -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -ic DevelopmentCA.cer -iv developmentCA.pvk -sv SSLCert.pvk SSLCert.cer
pvk2pfx -pvk SSLCert.pvk -spc SSLCert.cer -pfx SSLCert.pfx -po 123456
Import certificate to local computer personal certificate
The third step is to generate a client certificate. After executing the command, the client certificate will be automatically added to the "Certificate-Current User" personal certificate.
makecert.exe -pe -ss My -sr CurrentUser -a sha1 -sky exchange -n "CN=ClientCertificatesTest"
-eku 1.3.6.1.5.5.7.3.2 -sk SignedByCA -ic DevelopmentCA.cer -iv DevelopmentCA.pvk
The fourth step is to configure IIS after the certificate is generated, add a binding to the website and select the https type, and select the SSL certificate we just created.
The fifth step is to change the SSL settings. I have set that SSL must be required. You can choose according to your actual situation.
The sixth step is to add an HTTPS filter to the program. The interface that adds this feature will first determine whether the request comes from HTTPS
publicclassRequireHttpsAttribute : AuthorizationFilterAttribute
{
publicoverridevoid OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = newHttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase = "HTTPS Required"
};
}
else
{
base.OnAuthorization(actionContext);
}
}
{
publicoverridevoid OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = newHttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase = "HTTPS Required"
};
}
else
{
base.OnAuthorization(actionContext);
}
}
}
Finally, we test whether SSL works
publicstaticvoid Test()
{
var secure = newSecureString();
foreach (char s in"password") //password为导出的证书安全密码
{
secure.AppendChar(s);
}
var handler = newWebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.UseProxy = false;
string path = @"C:\test.pfx";
var certificate = newX509Certificate2(path, secure);
handler.ClientCertificates.Add(certificate);
ServicePointManager
.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
using (var client = newHttpClient(handler))
using (var content = newMultipartFormDataContent())
{
var arg = 1;
var url = string.Format(@" https://localhost:4438/api/test?arg={0}" ,arg);
var result = client.PostAsync(url, content).Result.Content.ReadAsStringAsync();
Console.WriteLine(string.Format("[{0}]", result.Result));
}
{
var secure = newSecureString();
foreach (char s in"password") //password为导出的证书安全密码
{
secure.AppendChar(s);
}
var handler = newWebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.UseProxy = false;
string path = @"C:\test.pfx";
var certificate = newX509Certificate2(path, secure);
handler.ClientCertificates.Add(certificate);
ServicePointManager
.ServerCertificateValidationCallback +=
(sender, cert, chain, sslPolicyErrors) => true;
using (var client = newHttpClient(handler))
using (var content = newMultipartFormDataContent())
{
var arg = 1;
var url = string.Format(@" https://localhost:4438/api/test?arg={0}" ,arg);
var result = client.PostAsync(url, content).Result.Content.ReadAsStringAsync();
Console.WriteLine(string.Format("[{0}]", result.Result));
}
}