我正在尝试使用客户端证书通过 ssl 和客户端身份验证来保护我的 RESTful WebApi 服务。
测试;我已经生成了一个自签名证书并将其放在本地计算机的 Trusted Root Certification Authorities 文件夹中您的安全工具没有ca安全证书,并且我已经生成了一个“服务器”和“客户端”证书。到服务器的标准 https 工作正常。
但是我在服务器中有一些代码来验证证书,当我使用提供我的客户端证书的测试客户端进行连接并且测试客户端返回 403 Forbidden 状态时您的安全工具没有ca安全证书,它永远不会被调用。
这意味着服务器在到达我的验证码之前未能通过我的证书。但是,如果我启动 fiddler,它知道需要客户端证书并要求我向 My Documents\Fiddler2 提供一个。我给了它我在测试客户端中使用的相同客户端证书,我的服务器现在可以工作并接收我期望的客户端证书!这意味着 WebApi 客户端没有正确发送证书,我下面的客户端代码与我发现的其他示例几乎相同。
static async Task RunAsync()
{
try
{
var handler = new WebRequestHandler();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(GetClientCert());
handler.ServerCertificateValidationCallback += Validate;
handler.UseProxy = false;
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("https://hostname:10001/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
var response = await client.GetAsync("api/system/");
var str = await response.Content.ReadAsStringAsync();
Console.WriteLine(str);
}
} catch(Exception ex)
{
Console.Write(ex.Message);
}
}
任何想法为什么它在提琴手中有效但在我的测试客户端中无效?
编辑:这是 GetClientCert() 的代码
private static X509Certificate GetClientCert()
{
X509Store store = null;
try
{
store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectName, "Integration Client Certificate", true);
if (certs.Count == 1)
{
var cert = certs[0];
return cert;
}
}
finally
{
if (store != null)
store.Close();
}
return null;
}
授予测试代码不处理空证书,但我正在调试以确保找到正确的证书。