C# 访问托管在Azure Worker角色中的ApiController中的客户端证书

C# 访问托管在Azure Worker角色中的ApiController中的客户端证书,c#,azure,azure-worker-roles,client-certificates,asp.net-apicontroller,C#,Azure,Azure Worker Roles,Client Certificates,Asp.net Apicontroller,这可能是一个重复的问题,但我仍然找不到任何可以解决我的问题的答案,所以再次发布 我有一个azure worker角色,并使用Owin selfhost向其添加了一个ApicController(请参阅以获取参考) 在我的自定义控制器中,我有一个POST api,它试图通过从请求对象提取证书来进行客户端证书身份验证,但当部署到azure cemulator时,证书总是为空 以下是我的示例客户机代码: enter code here 公共静态异步任务GetResponseAsync(WebApiR

这可能是一个重复的问题,但我仍然找不到任何可以解决我的问题的答案,所以再次发布

我有一个azure worker角色,并使用Owin selfhost向其添加了一个ApicController(请参阅以获取参考)

在我的自定义控制器中,我有一个POST api,它试图通过从请求对象提取证书来进行客户端证书身份验证,但当部署到azure cemulator时,证书总是为空

以下是我的示例客户机代码:

enter code here
公共静态异步任务GetResponseAsync(WebApiRequestInfo WebApiRequestInfo)

控制器代码如下所示:

[HttpPost]
        public async Task<HttpResponseMessage> GetPackage([FromBody]PackageInfo packageInfo)
        {
            string correlationId = null;
            var logger = TraceLogger<LogData>.Logger;

            try
            {
                if (string.IsNullOrEmpty(packageInfo.Partner))
                {
                    throw new ArgumentException("Partner undefined");
                }

                if (string.IsNullOrEmpty(packageInfo.ServiceEnvironment))
                {
                    throw new ArgumentException("ServiceEnvironment undefined");
                }

                if (string.IsNullOrEmpty(packageInfo.StorageEnvironment))
                {
                    throw new ArgumentException("StorageEnvironment undefined");
                }

                var cert1 = Request.GetClientCertificate();// this is always null
}
[HttpPost]
公共异步任务GetPackage([FromBody]PackageInfo PackageInfo)
{
字符串correlationId=null;
var记录器=TraceLogger.logger;
尝试
{
if(string.IsNullOrEmpty(packageInfo.Partner))
{
抛出新ArgumentException(“合作伙伴未定义”);
}
if(string.IsNullOrEmpty(packageInfo.ServiceEnvironment))
{
抛出新ArgumentException(“ServiceEnvironment undefined”);
}
if(string.IsNullOrEmpty(packageInfo.StorageEnvironment))
{
抛出新的ArgumentException(“StorageEnvironment undefined”);
}
var cert1=Request.GetClientCertificate();//此值始终为空
}

是否有我遗漏的东西,或者这是azure emulator的设计。我想在部署到云服务之前澄清这一点,以确保这里没有遗漏任何东西。任何解决这一问题的建议都会非常有用。

根据我的测试,我可以访问ASP.NET Web API中的客户端证书(托管在Azure Worker角色中)控制器操作。以下示例代码供您参考

TestController.cs

public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        return new HttpResponseMessage()
        {
            Content = new StringContent("Hello from OWIN!")
        };
    }
    public HttpResponseMessage Get(int id)
    {
        var Thumbprint = Request.GetClientCertificate().Thumbprint.ToString();
        string msg = String.Format("Hello from OWIN (id = {0})", id);
        return new HttpResponseMessage()
        {
            Content = new StringContent(msg)
        };
    }
}
在控制台应用程序中发送请求

X509Certificate2 certificate = new X509Certificate2(certName, password);

var Thumbprint = certificate.Thumbprint.ToString();

Console.WriteLine($"client certificate Thumbprint: {Thumbprint}");

WebRequestHandler requestHandler = new WebRequestHandler();

requestHandler = new WebRequestHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
requestHandler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

requestHandler.ClientCertificates.Add(certificate);


using (var client = new HttpClient(requestHandler))
{   
    HttpResponseMessage response = await client.GetAsync("https://127.0.0.1:9527/test/5");

    if (response.IsSuccessStatusCode)
    {
        string content = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Received response: {content}");
    }
    else
    {
        Console.WriteLine($"Error, received status code {response.StatusCode}: {response.ReasonPhrase}");
    }
}
可以在Web API控制器操作中访问客户端证书

控制台应用程序输出


问题出在证书颁发机构,IIS根据该机构从请求中筛选出证书。使用正确的证书并将CA列入白名单后,所有证书都开始正常工作。

请检查
webApiRequestInfo.BaseUrl
,它是http还是https?您的证书是自签名证书还是由作为服务器tr的受信任CA签名usted列表?在我的测试中,我使用的是自签名证书。
X509Certificate2 certificate = new X509Certificate2(certName, password);

var Thumbprint = certificate.Thumbprint.ToString();

Console.WriteLine($"client certificate Thumbprint: {Thumbprint}");

WebRequestHandler requestHandler = new WebRequestHandler();

requestHandler = new WebRequestHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
requestHandler.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

requestHandler.ClientCertificates.Add(certificate);


using (var client = new HttpClient(requestHandler))
{   
    HttpResponseMessage response = await client.GetAsync("https://127.0.0.1:9527/test/5");

    if (response.IsSuccessStatusCode)
    {
        string content = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Received response: {content}");
    }
    else
    {
        Console.WriteLine($"Error, received status code {response.StatusCode}: {response.ReasonPhrase}");
    }
}