HttpRequestMessage.GetClientCertificate() returns null in Web API(HttpRequestMessage.GetClientCertificate() 在 Web API 中返回 null)
问题描述
我有一个 .NET4.5 WebAPI 2 应用程序,它使用 SSL 客户端证书进行一些自定义安全相关检查.
I have a .NET4.5 WebAPI 2 app that uses SSL Client Certificates for some custom security related checks.
在调试应用程序时,request.GetClientCertificate()
为任何服务调用返回 null
,无论我到目前为止尝试了什么.
When debugging the app, request.GetClientCertificate()
returns null
for any service call, no matter what I tried so far.
经过测试的代码:
基本上,在我的服务方面,我有一个类似这样的方法:
Basically, on my service's side, I have a method that goes something like this:
class CertificateChecker : ICertificateChecker
{
public bool Check(HttpRequestMessage request)
{
var cert = request.GetClientCertificate();
}
}
我的单元测试使用 request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert)
附加到请求的客户端证书通过(证书完全符合预期,验证工作等等).
My unit tests with the client cert attached to the request using request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert)
pass (the cert comes out exactly as expected, validations work, and so on).
但是,当我使用带有 HttpClient
调用实际 WebAPI 应用程序的测试时,在服务端的 request.GetClientCertificate()
行设置断点,同一行返回 null.
However, when I use a test with an HttpClient
calling the actual WebAPI app, with the break point set at the request.GetClientCertificate()
line on service side, the same line returns null.
这是我尝试过的:
客户证书:
- 创建了一个假 CA 并将其放入受信任的 CA 存储中(尝试了 LocalMachine 和当前用户).
- 创建了一个由该假 CA 签名的客户端身份验证 (1.3.6.1.5.5.7.3.2) 证书并将其放入个人存储区(LocalMachine 和当前用户).
(基本上,遵循 https://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/ 和类似博客)
(basically, followed https://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/ and similar blogs)
在我使用 HttpClient
调用服务的测试中,通过以下方式附加客户端证书(均无效):
On my test that calls the service using HttpClient
, attached the client cert in the following ways (none of which worked):
使用
WebRequestHandler
并将ClientCertificateOptions
设置为 Manual,并将证书添加到ClientCertificates
集合中.
Using
WebRequestHandler
withClientCertificateOptions
set to Manual and the cert added to theClientCertificates
collection.
using (var handler = new WebRequestHandler())
{
var cert = GetTestCert();
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
handler.ClientCertificates.Add(cert);
// and so on...
}
使用 HttpRequestMessage
,将证书添加为属性,并将密钥设置为 HttpPropertyKeys.ClientCertificateKey
(这种方法在上述单元测试时有效).
Using the HttpRequestMessage
, adding the cert as a property with the key set to HttpPropertyKeys.ClientCertificateKey
(this approach works when unit testing as described above).
request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert);
cert
变量在这两种情况下都设置为预期的 X509Certificate2
对象.
The cert
variable is set to the expected X509Certificate2
object in both cases.
托管:
IISExpress:尝试在 IISExpress 中运行应用程序.
IISExpress: Tried to run the app in IISExpress.
编辑 applicationhost.config 并启用 iisClientCertificateMappingAuthentication
设置为true"和以下访问设置(均无效):
Edited applicationhost.config with iisClientCertificateMappingAuthentication enabled
set to "true" and the following access settings (neither worked):
<access sslFlags="Ssl, SslNegotiateCert" />
<access sslFlags="SslNegotiateCert" />
本地 IIS将 Web 应用设置为在我的本地计算机上的 IIS 中运行
Local IIS Set the web app to run in IIS on my local machine
- IIS 中的站点使用受信任的证书配置了 HTTPS 绑定.
- Web 应用配置为使用 https 协议并启用 IIS 客户端证书映射身份验证.
- 尝试了两种访问选项组合(
Ssl、SslNegotiateCert
和SslNegotiateCert
)(通过配置编辑器)
- The site in IIS is configured with an HTTPS binding using a trusted certificate.
- Web app configured to use https protocol with IIS Client Cert mapping authentication enabled.
- Tried both the access option combinations (
Ssl, SslNegotiateCert
andSslNegotiateCert
) (via configuration editor)
在这两种情况下,当使用 web 浏览器通过 https url 访问 web api 时,我可以毫无问题地显示家庭控制器的索引视图(因此,服务器端证书是可信的).
In both cases, when accessing the web api via the https url using a web browser, I get the index view of the home controller to show without issue (so, the server side cert is trusted).
推荐答案
我知道它有点老了,但我遇到了同样的问题,我通过followinfg这篇文章解决了它:
I know it is a bit old but I was facing the same issue and i solved it by followinfgthis article:
https://improveandrepeat.com/2017/07/how-to-configure-iis-express-to-accept-ssl-client-certificates/
问题是 IIS 服务器上的配置,也可以在 IIS express 上进行修改.如果链接不可用,我会报告它.
The problem was a configuration on the IIS server, which can be modified also on IIS express. I report it in case the link will not be available.
对于 IIS 更改服务器配置文件,对于 IIS Express 修改您的解决方案下的文件位于.vsconfigapplicationhost.config
For IIS change the server configuration file, for IIS Express modify the file under your solution located in .vsconfigapplicationhost.config
搜索元素内部调用的xml元素:
Search for an xml element called inside a element:
<security>
<access sslFlags="None" />
默认配置不支持 SSL 客户端证书.您需要修改 sslFlags 属性以包含以下选项:Ssl、SslNegotiateCert、SslRequireCert
The default configuration has no support for SSL client certificates. You need to modify the sslFlags attribute to include these options: Ssl, SslNegotiateCert, SslRequireCert
<security>
<access sslFlags="Ssl, SslNegotiateCert, SslRequireCert" />
下一步是找到元素:
<iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
如果将 enabled 更改为 true,IIS Express 将开始接受客户端证书:
If you change enabled to true, IIS Express will start accepting client certificates:
<iisClientCertificateMappingAuthentication enabled="true">
</iisClientCertificateMappingAuthentication>
您现在需要重新启动 Visual Studio 和 IIS Express.IIS Express 可以使用系统托盘中的图标重新启动.
You now need to restart Visual Studio and IIS Express. IIS Express can be restarted using the icon in your system tray.
从现在开始,您将被要求提供客户端证书,您可以在 Visual Studio 中调试整个应用程序.这可能看起来不像就像一个很大的改进,但相信我,它使调试变得更加简单.
From now on you will be asked for a client certificate and you can debug the whole application inside Visual Studio. This may not look like a big improvement, but trust me, it makes debugging much simpler.
希望这可以帮助其他人:-)
Hope this could help someone else :-)
这篇关于HttpRequestMessage.GetClientCertificate() 在 Web API 中返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:HttpRequestMessage.GetClientCertificate() 在 Web API 中返回 null
基础教程推荐
- c# Math.Sqrt 实现 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- SSE 浮点算术是否可重现? 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- MS Visual Studio .NET 的替代品 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- rabbitmq 的 REST API 2022-01-01