HttpRequestMessage.GetClientCertificate() 在 Web API 中返回 null [英] HttpRequestMessage.GetClientCertificate() returns null in Web API

查看:26
本文介绍了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 with ClientCertificateOptions set to Manual and the cert added to the ClientCertificates 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、SslNegotiateCertSslNegotiateCert)(通过配置编辑器)
    • 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 and SslNegotiateCert) (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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆