WebAPI 端的 WebRequest 客户端证书为空

WebRequest client certificate null on WebAPI side

我有一个用 [x509Authorize] 属性装饰的 WebApi 控制器操作。我正在本地调试此端点 - 同时 运行 一个尝试调用此端点的控制台应用程序。

客户端

这是客户端代码 - 稍微简化了:

X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\Temp\ht-android-client.pfx");               
HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://localhost:44300/api/mobile/predict");
Request.ClientCertificates.Add(Cert);
HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
....

我断言 Cert 是正确的证书。我已经在我的 CurrentUser\Personal 商店和 LocalMachine\Personal 商店中安装了 .pfx - 并按照建议 here 进行了修改以从该商店获取证书,但事实并非如此似乎有所作为:

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var Cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Android", true)[0];

服务器端

我正在使用以下代码监听 WebAPI 端点:

public class x509AuthorizeAttribute : AuthorizeAttribute
{
    public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        var cert = actionContext.Request.GetClientCertificate();
       // value of 'cert' is null

我首先在控制台应用程序中设置了一个断点 - 查看是否选择了正确的证书。然后我在服务器上打了断点,看到.GetClientCertificate()的值是null。我究竟做错了什么?其他 SO 问题 1 and 2 对我没有任何帮助。

有关证书的其他信息

我已经创建了一个安装在 LocalMachine\Trusted root CA 商店中的自签名 CA 证书。我已经创建了 android 客户端证书 - 并使用我的自签名 CA 证书对其进行了签名。然后我将其转换为 pkcs12 文件。这是客户端正在使用的证书 - 它也安装在我的个人商店(机器和 currentUser )并且有效(你可以看到链回到 ROOT CA 证书)。

此外 - 证书的用途设置为 clientAuth:

所以问题确实是服务器需要在 web.config 中设置以下内容以强制 IIS 启动 SSL 证书协商:

<security>
    <access sslFlags="SslNegotiateCert" />
</security>

如果不存在 - 证书将被忽略,您将在 GetClientCertificate() 调用中获得 null

然而,这意味着我的 WebAPI 的 所有 客户端现在都被迫提供有效的证书 - 所以我最初的想法是只有一个控制器方法需要证书似乎是不可能的.

由于 Azure 云服务的限制,在 web.config 中设置此配置参数存在挑战。但是 - this 答案为此提供了解决方案。

编辑

附带说明 yet 在 ASP.NET vNext ( v rc-01-final )

中支持