【发布时间】:2019-04-06 01:23:05
【问题描述】:
我正在尝试构建一个 AuthorizeAttribute,它要求 HTTPRequest 包含指定的客户端证书。
我在这里找到了我认为是关于这些问题的一系列博客文章,作者是 Andras Nemes:
Using Client Certificates in .NET Part 2 Creating Self-Signed Client Certificates
Using Client Certificates in .NET Part 3 -Installing the Client Certficate
Using Client Certificates in .NET Part 4 - Working with Client Certificates in Code
Using Client Certificates in .NET Part 5 - Working with Client Certificates in a Web Project
Using Client Certificates in .NET Part 6 - Setting up Client Certificates for Local Test Usage
我有一个测试 Web API 项目在 VS2015 中运行,针对在我的本地 IIS 上运行的站点进行调试,而不是 IIS Express,配置了 https 并设置了 SSL 设置以允许客户端证书。
我很确定它设置正确,因为它适用于我创建的证书之一。
我的属性很简单:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class KtRequireClientCertAttribute : AuthorizeAttribute
{
public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
{
byte[] cert = HttpContext.Current.Request.ClientCertificate.Certificate;
// if the ClientCertificate is empty, pass null
X509Certificate2 suppliedCert = cert.Any() ? new X509Certificate2(cert) : null;
if (suppliedCert != null && isExpectedCert(suppliedCert)
return;
base.OnAuthorization(actionContext);
}
}
我的问题 - 这适用于我上周按照 Andras 的说明创建的证书之一。
ClientCertificate.Certificate 是一个包含 808 个元素的 byte[],X509Certificate2 构造正确,我的验证逻辑按预期工作。
但是对于我今天尝试创建的每个证书,HttpContext.Current.Request.ClientCertificate.Certificate 都是空的。
我正在制作证书:
MAKECERT.EXE -ic DevRootCertificate.cer -iv DevRootCertificate.pvk -pe -sv testclientcert.pvk -a sha1 -n "CN=testclientcert" -len 2048 -b 01/01/2015 -e 01/01/2030 -sky exchange testclientcert.cer -eku 1.3.6.1.5.5.7.3.2
我的测试客户端应用很简单:
using (var requestHandler = new WebRequestHandler())
{
var certificate = new X509Certificate2(certificateFile);
requestHandler.ClientCertificates.Add(certificate);
var url = new Uri(baseUrl);
using (var client = new HttpClient(requestHandler){BaseAddress = url})
{
var response = client.GetAsync(endPoint).Result;
response.EnsureSuccessStatusCode();
var content = response.Content.ReadAsStringAsync().Result;
Console.Out.WriteLine(JToken.Parse(content).ToString(Formatting.Indented));
}
}
问题是为什么一个证书被传递给属性而另一个没有?
附加信息:
我在同一个服务器上运行同一个客户端,在我本地机器上的 IIS 上运行。该网站被配置为接受但不要求客户端证书。
有效的测试运行和无效的测试运行之间的唯一区别是我从哪个 .cer 文件加载证书。
我不确定有效的证书是否有私钥,但有效的文件是 .cer,而不是 .pfx。
无效的文件也是 .cer。我知道它没有签名。所以我创建了一个签名证书并尝试使用 .pfx 文件构建 X509Certificate2() 。我什至没有访问服务器就收到 403 错误。
【问题讨论】:
-
仔细检查您使用的是
https://而不是http:// -
我正在使用与失败证书相同的证书 URL。
-
一个是 PFX 而另一个是 CER 吗?您需要私钥才能正确使用它; ClientCertificates 中 cert.HasPrivateKey 为 false 的任何证书都将被忽略。
-
您是否连接到相同的服务器?并非所有 TLS (HTTPS) 服务器都需要通过证书进行客户端身份验证...
标签: c# ssl iis ssl-certificate