我正在尝试使用客户端证书保护我的RESTful WebApi服务的SSL和客户端身份验证。
为了测试,我生成了一个自签名证书并将其放置在本地计算机的受信任根证书颁发机构文件夹中,并生成了“服务器”和“客户端”证书。与服务器的标准https连接正常工作。
但是,当我使用测试客户端连接并提供客户端证书时,服务器中用于验证证书的代码从未被调用,并返回403禁止状态。
这意味着服务器在到达我的验证代码之前就已经拒绝了我的证书。然而,如果我启动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);
}
}
有什么想法为什么Fiddler可以工作而我的测试客户端却不行?
编辑:这是获取客户端证书的代码:
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;
}
虽然测试代码没有处理 null 证书,但我正在调试以确保找到正确的证书。
仅当它与服务器信任的根之一具有信任链时,客户端才会使用客户端证书(来自WebRequestHandler.ClientCertificates集合)
。 我猜测您的证书没有受到信任(自签名)。 - Khanh TO