HTT prequestMessage.GetClientCertificate()返回的Web API空 [英] HttpRequestMessage.GetClientCertificate() returns null in Web API

查看:941
本文介绍了HTT prequestMessage.GetClientCertificate()返回的Web API空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

在调试应用程序, request.GetClientCertificate()收益的任何服务电话,不管我到目前为止已经试过。

被测code:

基本上,在我服务的身边,我有一个是这样的一个方法:

 类CertificateChecker:ICertificateChecker
{
    公共BOOL检查(HTT prequestMessage要求)
    {
        VAR证书= request.GetClientCertificate();
    }
}

我单位与连接到使用 request.Properties.Add(HttpPropertyKeys.ClientCertificateKey,CERT)传请求的客户端证书测试(CERT的问世正好符合市场预期,验证工作,等等)。

然而,当我使用测试与的HttpClient 调用实际的WebAPI应用程序,设置断点处的 request.GetClientCertificate() 在服务端线,在同一行返回null。

下面是我的尝试:

客户端证书:


  • 创建一个假的CA,放入信任的CA存储(都试过LOCALMACHINE和当前用户)。

  • 创建一个客户端身份验证(1.3.6.1.5.5.7.3.2)通过伪造CA签名的证书,把它变成了个人存储(LOCALMACHINE和当前用户)。

(基本上,随后<一href=\"https://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/\" rel=\"nofollow\">https://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/和类似的博客)

在我的测试中使用的HttpClient ,附着在以下几个方面(其中没有工作)的客户端证书调用该服务:


  • 使用 WebRequestHandler ClientCertificateOptions 设置为手动和证书添加到 ClientCertificates 集合。

     使用(VAR处理器=新WebRequestHandler())
    {
         VAR证书= GetTestCert();
         handler.ClientCertificateOptions = ClientCertificateOption.Manual;
         handler.ClientCertificates.Add(CERT);     // 等等...
    }


  • 使用的Htt prequestMessage ,添加证书与按键到属性 HttpPropertyKeys.ClientCertificateKey (这种方法的工作原理,当单元测试如上所述)。

      request.Properties.Add(HttpPropertyKeys.ClientCertificateKey,证书);


证书变量设置为预期的 X509Certificate2 对象在两种情况下。

主机:


  • IISEx preSS:试图运行在IISEx preSS应用<​​/ P>

    iisClientCertificateMappingAuthentication编辑对ApplicationHost.config启用设置为真和下面的访问设置(既不工作):

     &LT;获得sslFlags =SSL,SslNegotiateCert/&GT;
    &LT;获得sslFlags =SslNegotiateCert/&GT;


  • 本地IIS
    将Web应用程序在IIS中我的本地机器上运行


    • 在IIS的站点配置了使用受信任的证书的HTTPS绑定。

    • 网络应用程序配置为使用https协议启用IIS客户端证书映射身份验证。

    • 试用过访问选项组合( SSL,SslNegotiateCert SslNegotiateCert )(通过配置编辑器)


在这两种情况下,使用网页浏览器通过HTTPS URL访问的Web API时,我回到家控制器的索引视图来显示没有问题(所以,服务器端证书被信任)。


解决方案

大详细了解您的问题的信息。

我要承担的问题是与连接的客户端证书瓦特/ HttpClient的,因为你不能查看在这种情况下服务器端的证书。所有的主机和服务器端证书的配置听起来不错。


  1. 我想请确保您要连接的 X509Certificate2证书变量是在您的本地证书存储区中存在的(我不知道一个公钥什么存储位置要存储在此)(你可以检查使用程序mmc.exe)。另外,还要确保该公钥具有自HttpClient的用它的私有密钥将需要签署的请求。


  2. 在您的code片段你有使用(VAR处理器=新WebRequestHandler())您code的其余部分之前。请确保您构建你的 HttpClient的客户端=新的HttpClient(处理器)中的使用,以及或处理程序进行处理。


否则处理程序创建效果很不错。

祝你好运!

I have a .NET4.5 WebAPI 2 app that uses SSL Client Certificates for some custom security related checks.

When debugging the app, request.GetClientCertificate() returns null for any service call, no matter what I tried so far.

The Tested Code:

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();
    }
}

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).

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.

Here's what I tried:

Client Certs:

  • Created a fake CA and put it into trusted CA store (tried both LocalMachine and current user).
  • Created a Client Authentication (1.3.6.1.5.5.7.3.2) cert signed by that Fake CA and placed it into the Personal store (LocalMachine and Current User).

(basically, followed https://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/ and similar blogs)

On my test that calls the service using HttpClient, attached the client cert in the following ways (none of which worked):

  • 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...
    }
    

  • 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);
    

The cert variable is set to the expected X509Certificate2 object in both cases.

Hosting:

  • IISExpress: Tried to run the app in IISExpress.

    Edited applicationhost.config with iisClientCertificateMappingAuthentication enabled set to "true" and the following access settings (neither worked):

    <access sslFlags="Ssl, SslNegotiateCert" />
    <access sslFlags="SslNegotiateCert" />
    

  • Local IIS Set the web app to run in IIS on my local machine

    • 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)

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).

解决方案

Great detailed information about your problem.

I'm going to assume the issue is with attaching the client certificate w/ HttpClient, since you cannot view the certificate on the server side in that situation. All of the hosting and server side certificate configuration sounds good.

  1. I would make sure that the X509Certificate2 cert variable that you are attaching is a public key that exists in your local certificate store (I'm not sure what store location you are storing this in) (you can check using mmc.exe). Also make sure that public key has a private key with it since the HttpClient will need that to sign the requests.

  2. In your code snippet you have using (var handler = new WebRequestHandler()) before the rest of your code. Make sure you are constructing your HttpClient client = new HttpClient(handler) in the using as well or the handler will be disposed.

Otherwise the handler creation looks good.

Good luck!

这篇关于HTT prequestMessage.GetClientCertificate()返回的Web API空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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