我想使用客户端证书来保护我的RESTful WebApi服务使用ssl和客户端身份验证。WebApi HttpClient不发送客户端证书
测试;我生成了一个自签名证书并放置在本地计算机,受信任的根证书颁发机构文件夹中,并生成了“服务器”和“客户端”证书。 服务器的标准https正常运行。
不过,我有一些代码在服务器验证证书,这当我连接使用我的测试客户端,它提供我的客户证书和测试客户端返回403个禁止状态不会被调用。
这imples服务器失败我的证书达到我的验证代码之前。 但是,如果我激起了提琴手它知道客户证书是必需的,并要求我提供一个我的文档\ 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;
}
授予测试代码不处理空证书,但我调试到enssure了正确的证书所在。
你检查这GetClientCert返回你所期望的证书? – csgero
是:) GetClientCert所做的是从localmachine个人存储中查找客户端证书,这与我给小提琴手的证书相同。 但是,即使它是一个不同的证书我会期望服务器验证代码被调用? – Tronneh
取决于服务的托管方式。例如,IIS会执行证书验证,并会返回403而不会调用您的代码。 – csgero