【问题标题】:HttpRequestMessage.GetClientCertificate() returns null in Web APIHttpRequestMessage.GetClientCertificate() 在 Web API 中返回 null
【发布时间】:2014-04-02 16:49:04
【问题描述】:

我有一个 .NET4.5 WebAPI 2 应用程序,它使用 SSL 客户端证书进行一些自定义安全相关检查。

在调试应用程序时,request.GetClientCertificate() 会为任何服务调用返回 null,无论我到目前为止尝试了什么。

经过测试的代码:

基本上,在我的服务方面,我有一个类似这样的方法:

class CertificateChecker : ICertificateChecker
{
    public bool Check(HttpRequestMessage request)
    {
        var cert = request.GetClientCertificate();
    }
}

我的单元测试使用request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert) pass 附加到请求的客户端证书(证书完全符合预期,验证工作等等)。

但是,当我使用 HttpClient 调用实际 WebAPI 应用程序的测试时,在服务端的 request.GetClientCertificate() 行设置断点时,同一行返回 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/和类似博客)

在我使用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(这种方法在上述单元测试时有效)。

    request.Properties.Add(HttpPropertyKeys.ClientCertificateKey, cert);
    

cert 变量在这两种情况下都设置为预期的X509Certificate2 对象。

托管:

  • IISExpress:尝试在 IISExpress 中运行应用程序。

    编辑 applicationhost.config 并将 iisClientCertificateMappingAuthentication enabled 设置为“true”和以下访问设置(均无效):

    <access sslFlags="Ssl, SslNegotiateCert" />
    <access sslFlags="SslNegotiateCert" />
    
  • 本地 IIS 将 Web 应用设置为在我的本地计算机上的 IIS 中运行

    • IIS 中的站点使用受信任的证书配置了 HTTPS 绑定。
    • Web 应用程序配置为使用 https 协议并启用 IIS 客户端证书映射身份验证。
    • 尝试了两种访问选项组合(Ssl, SslNegotiateCertSslNegotiateCert)(通过配置编辑器)

在这两种情况下,当使用 web 浏览器通过 https url 访问 web api 时,我可以毫无问题地显示家庭控制器的索引视图(因此,服务器端证书是可信的)。

【问题讨论】:

    标签: c# iis asp.net-web-api ssl-certificate iis-express


    【解决方案1】:

    我知道它有点旧,但我遇到了同样的问题,我通过以下文章解决了它:

    https://improveandrepeat.com/2017/07/how-to-configure-iis-express-to-accept-ssl-client-certificates/

    问题是 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" />
    

    下一步是找到元素 :

    <iisClientCertificateMappingAuthentication enabled="false"></iisClientCertificateMappingAuthentication>
    

    如果将 enabled 更改为 true,IIS Express 将开始接受客户端 证书:

    <iisClientCertificateMappingAuthentication enabled="true">
                </iisClientCertificateMappingAuthentication>
    

    您现在需要重新启动 Visual Studio 和 IIS Express。 IIS Express 可以 使用系统托盘中的图标重新启动。

    从现在开始,您将被要求提供客户端证书,您可以 在 Visual Studio 中调试整个应用程序。这可能看起来不像 就像一个很大的改进,但相信我,它使调试变得更加简单。

    希望这可以帮助其他人:-)

    【讨论】:

      【解决方案2】:

      关于您的问题的详细信息。

      我将假设问题在于使用 HttpClient 附加客户端证书,因为在这种情况下您无法在服务器端查看证书。所有托管和服务器端证书配置听起来都不错。

      1. 我会确保您附加的 X509Certificate2 cert 变量是本地证书存储中存在的公钥(我不确定您将其存储在哪个存储位置)(您可以检查使用 mmc.exe)。还要确保公钥有一个私钥,因为 HttpClient 需要它来签署请求。

      2. 在您的代码 sn-p 中,您在其余代码之前有 using (var handler = new WebRequestHandler())。确保你也在使用中构造你的HttpClient client = new HttpClient(handler),否则处理程序将被释放。

      否则处理程序创建看起来不错。

      祝你好运!

      【讨论】:

      • 感谢您的快速响应!我确实有一个可导出的私钥用于存储中的证书(它位于使用HttpClient 运行服务和测试的机器上的个人存储中)并且我已经使用了 HttpClient(handler) 构造函数。我还尝试从 pfx 获取相同的证书(包括私钥)——但我得到了相同的结果(正确的证书被实例化,但从未到达服务器端)。
      • 听起来客户端构造正确。服务器是否知道预期的客户端凭据类型?通常我使用HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(hostAddres); config.ClientCredentialType = HttpClientCredentialType.Certificate; 来配置服务器以接受客户端证书作为凭据。
      • 我正在使用 IISExpress 或本地 IIS 进行托管,所以我不确定 HttpSelfHostConfiguration 是否适用?是否有另一种 HttpConfiguration 类型具有类似的方式来配置 IIS 或 IISExpress 中托管的 Web API 的凭据类型?
      • @dolbomir ,我知道那是很久以前的事了,但你有运气吗?我在使用 HttpClient 和非常简单的 WebApi2 服务时遇到了同样的问题
      • @dolbomir,我也遇到了这个问题,有人找到解决方法了吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-21
      • 2021-06-11
      • 1970-01-01
      • 2018-11-09
      • 1970-01-01
      • 2015-08-14
      相关资源
      最近更新 更多