C# HttpRequestMessage.GetClientCertificate()在Web API中返回null
我有一个.NET4.5 WebAPI 2应用程序,它使用SSL客户端证书进行一些自定义的安全相关检查 调试应用程序时,C# HttpRequestMessage.GetClientCertificate()在Web API中返回null,c#,iis,asp.net-web-api,ssl-certificate,iis-express,C#,Iis,Asp.net Web Api,Ssl Certificate,Iis Express,我有一个.NET4.5 WebAPI 2应用程序,它使用SSL客户端证书进行一些自定义的安全相关检查 调试应用程序时,request.GetClientCertificate()对任何服务调用返回null,无论我目前尝试了什么 测试代码: 基本上,在我的服务方面,我有一个类似这样的方法: class CertificateChecker : ICertificateChecker { public bool Check(HttpRequestMessage request) {
request.GetClientCertificate()
对任何服务调用返回null
,无论我目前尝试了什么
测试代码:
基本上,在我的服务方面,我有一个类似这样的方法:
class CertificateChecker : ICertificateChecker
{
public bool Check(HttpRequestMessage request)
{
var cert = request.GetClientCertificate();
}
}
使用request.Properties.Add(HttpPropertyKeys.ClientCertificateKey,cert)
pass(证书完全按照预期生成,验证工作,等等),使用附加到请求的客户端证书进行单元测试
但是,当我使用一个调用实际WebAPI应用程序的HttpClient
测试时,断点设置在服务端的request.GetClientCertificate()
行,同一行返回null
以下是我尝试过的:
客户证书:
- 创建了一个伪CA并将其放入可信CA存储(尝试了LocalMachine和当前用户)
- 创建了由该伪造CA签名的客户端身份验证(1.3.6.1.5.5.7.3.2)证书,并将其放入个人存储(LocalMachine和当前用户)
HttpClient
调用服务的测试中,以以下方式附加客户端证书(所有方式均无效):
- 使用
,将WebRequestHandler
设置为手动,并将证书添加到ClientCertificateOptions
集合中ClientCertificates
using (var handler = new WebRequestHandler()) { var cert = GetTestCert(); handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ClientCertificates.Add(cert); // and so on... }
- 使用
,将证书作为一个属性添加,并将密钥设置为HttpRequestMessage
(当进行如上所述的单元测试时,此方法有效)HttpPropertyKeys.ClientCertificateKey
cert
变量都设置为预期的X509Certificate2
对象
托管:
- IISExpress:尝试在IISExpress中运行应用程序
已编辑applicationhost.config,启用了
并将以下访问设置设置设置为“true”(均无效):iisClientCertificateMappingAuthentication
- 本地IIS
将web应用设置为在本地计算机上的IIS中运行
- IIS中的站点配置了使用受信任证书的HTTPS绑定
- 配置为使用https协议并启用IIS客户端证书映射身份验证的Web应用
- 尝试了两种访问选项组合(
和Ssl、SslNegotiateCert
)(通过配置编辑器)SslNegotiateCert
在这两种情况下,当使用web浏览器通过https url访问web api时,我会显示主控制器的索引视图而不会出现问题(因此,服务器端证书是可信的)。关于您的问题的详细信息 我将假设问题在于附加客户端证书w/HttpClient,因为在这种情况下,您无法在服务器端查看证书。所有的主机和服务器端证书配置听起来都不错
X509Certificate2 cert
变量是存在于本地证书存储中的公钥(我不确定您将其存储在哪个存储位置)(您可以使用mmc.exe进行检查)。还要确保公钥带有私钥,因为HttpClient需要私钥来签署请求HttpClient client=newhttpclient(handler)
,否则处理程序将被释放祝你好运 我知道这有点旧,但我也面临着同样的问题,我通过以下文章解决了这个问题: 问题是IIS服务器上的配置,也可以在IIS express上修改该配置。我报告它的情况下,链接将不可用 对于IIS,请更改服务器配置文件;对于IIS Express,请修改 解决方案下的文件位于中 .vs\config\applicationhost.config 在元素内搜索名为的xml元素:
<security>
<access sslFlags="None" />
默认配置不支持SSL客户端证书。
您需要修改sslFlags属性以包含以下选项:
Ssl、SslNegotiateCert、SslRequireCert
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
下一步是找到元素
:
如果将enabled更改为true,IIS Express将开始接受客户端
证书:
<iisClientCertificateMappingAuthentication enabled="true">
</iisClientCertificateMappingAuthentication>
现在需要重新启动Visual Studio和IIS Express。IIS Express can
使用系统托盘中的图标重新启动
从现在起,将要求您提供客户端证书,您可以
在VisualStudio中调试整个应用程序。这看起来可能不太好
这是一个很大的改进,但是相信我,它使调试变得更加简单
希望这能帮助其他人:-)感谢您的快速响应!我确实在存储中有证书的可导出私钥(它在使用
HttpClient
运行服务和测试的计算机上的个人存储中),并且我已经使用了HttpClient(handler)构造函数。我还尝试从pfx(包括私钥)获取相同的证书,但得到了相同的结果(正确的证书被实例化,但从未到达服务器端)。服务器是否知道需要什么类型的客户端凭据?通常我使用HttpSelfHostConfiguration config=newhttpselfhostconfiguration(hostAddres)代码>config.ClientCredentialType=HttpClientCredentialType.Certificate代码>到
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
<iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
<iisClientCertificateMappingAuthentication enabled="true">
</iisClientCertificateMappingAuthentication>