我们想要创建一个自签名证书并将其手动安装在客户端 PC 上,并将私钥标记为不可导出。 客户端调用 ASP.NET Web API,我们要检查是否安装了特定证书。
我们希望将其作为一种额外的身份验证方法,以确保只有有效的客户端才能调用 Web API。我们知道这不是防水的,因为仍然可以导出私钥,但我们还有其他额外的身份验证机制,例如用户密码。
我们怎样才能实现这一目标?或者有更好的方法来实现我们的目标吗?
对我来说,在服务器中创建自签名证书后,我将证书
Thumbprint
添加到我的客户端应用程序
private void setAppLocalSSL()
{
ServicePointManager.ServerCertificateValidationCallback += delegate (
object sender,
X509Certificate cert,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true; //Is valid
}
// this is the Thumbprint of my local cert
// your Cert Thumbprint instead of "0000000000000000"
if (cert.GetCertHashString().ToLower() == "0000000000000000")
{
return true;
}
return false;
};
}
调用
setAppLocalSSL
加载
注意:这是一个 WPF 应用程序。
三年后,.NET 7 出现了 Microsoft 的官方示例,介绍如何验证用户证书。
首先,安装 Microsoft.AspNetCore.Authentication.Certificate 包。之后,您可以在您的
Program.cs
中添加中间件:
builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate();
...并使用
OnAuthenticationFailed
和 OnCertificateValidated
: 实现您自己的验证
builder.Services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
.AddCertificate(options =>
{
options.Events = new CertificateAuthenticationEvents
{
OnCertificateValidated = context =>
{
var claims = new[]
{
new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer),
new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer)
};
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
context.Success();
return Task.CompletedTask;
}
};
});
如果您不知道用户正在使用的证书,您可以在
context.Fail("Wrong certificate!")
方法中调用 OnCertificateValidated
。