天青,ASP.NET 2.0的核心,调用后,在“客户端证书的凭据也未发现”使用HttpClient的

2019-09-28 18:49发布

我试图从ASP.NET核心(2.0.2)的Web API(在控制器内)调用第三方的基于HTTP的API。

在非Azure的环境中运行(Windows 7的框),当它成功。 与误差范围内Azure在一个应用程序服务运行时“的客户端证书凭据无法识别”失败。 代码和证书是环境之间是相同的。 两者都运行在IIS。

我削成码表列如下隔离我的问题。 而且我已经改变了的密码和URL的详细信息在这里的原因很明显。

[HttpGet]
public async Task<IActionResult> Get()
{
    string response = null;

    using (HttpClientHandler handler = new HttpClientHandler())
    {
        handler.ClientCertificateOptions = ClientCertificateOption.Manual;
        handler.SslProtocols = SslProtocols.Tls12;
        handler.ClientCertificates.Add(new X509Certificate2("Certificate/Cert.pfx", "<password-removed>"));
        using (HttpClient client = new HttpClient(handler))
        {
            using (HttpResponseMessage responseMessage = await client.PostAsync("https://some-domain.com/action.asp?sourceid=123&key=10101", null))
            {
                response = await responseMessage.Content.ReadAsStringAsync();
            }
        }
    }

    return Ok(response);
}

将所得的异常和调用堆栈如下:

System.Net.Http.HttpRequestException:发送请求时发生错误。 ---> System.Net.Http.WinHttpException:客户端证书的凭据未在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在System.Threading.Tasks.RendezvousAwaitable1.GetResult()在System.Net.Http认可。 WinHttpHandler.d__105.MoveNext()---内部异常堆栈跟踪的结尾---在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(工作任务)在System.Runtime。 CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务task)在System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()在System.Net.Http.HttpClient.d__58.MoveNext()---从以前的位置,其中的例外是堆栈跟踪的结尾抛出--- \ TestController.cs:线32

另一个有趣的事情是,我可以使用curl如下成功地执行这个帖子在Azure的应用服务控制台。 这里使用的.PEM文件从C#代码中使用的.pfx文件生成。

curl -s --data "" --cert .\Cert.pem:<password-removed> "https://some-domain.com/action.asp?sourceid=123&key=10101"

更新

我重构代码库,以简化问题的重复。 现在,我使用它,我上传到通过捻的应用服务在Azure和在库杜控制台运行一个控制台应用程序。 它失败,与上述相同的异常。

static void Main(string[] args)
{
    Console.WriteLine("Starting v3...");
    string response = null;

    try
    {
        using (HttpClientHandler handler = new HttpClientHandler())
        {
            handler.ClientCertificateOptions = ClientCertificateOption.Manual;
            handler.SslProtocols = SslProtocols.Tls12;
            Console.WriteLine("Loading Cert...");
            var cert = new X509Certificate2(certFilePath, certPassword);
            Console.WriteLine("Verifying Cert...");
            bool result = cert.Verify();
            Console.WriteLine($"Verified Cert: {result}"); // Variable result is 'True'here.
            handler.ClientCertificates.Add(cert);

            using (HttpClient client = new HttpClient(handler))
            {
                HttpContent content = new System.Net.Http.StringContent("");
                Console.WriteLine("Posting...");
                using (HttpResponseMessage responseMessage = client.PostAsync(url, content).Result) //  FAILS HERE!
                {
                    Console.WriteLine("Posted...");
                    Console.WriteLine("Reading Response...");
                    response = responseMessage.Content.ReadAsStringAsync().Result;
                    Console.WriteLine($"Response: {response}");
                }
            }
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine("BOOM!!!");
        exc = LogException(exc);
    }

    Console.WriteLine("Done!");
    Console.ReadLine();
}

请注意:我知道,这是不寻常的,因为我执行与查询参数的POST并没有实际的身体,但这一部分是不是在我的控制-它是由第三方所决定的。 我没有怀疑这是我的问题的一个因素,但我可能是大错。

我花了很多时间在这个伟大的交易,都碰了壁。

Answer 1:

解决的办法是更容易比预期的。 我需要用指纹在Azure的应用程序服务应用程序设置的值WEBSITE_LOAD_CERTIFICATES关键,但在Web服务器环境中运行时,这只会被拾起。 所以,我用来尝试找出问题我的控制台应用程序只能使我更加痛苦,因为它没有看到这些设置。

这篇文章是什么把我带到这个修复。

https://docs.microsoft.com/en-us/azure/app-service/app-service-web-ssl-cert-load



Answer 2:

您已经添加了他们的服务器证书到您的证书存储? 客户端证书用于你在哪里向他们发送一个证书,代表你相互验证的情况。 如果他们的证书通过了“众所周知”的测试,它不会有一个信任问题,但如果他们有一个自签名的证书,你必须捕捉他们的证书,并将其导入您的证书存储。



文章来源: Azure, ASP.NET Core 2.0, Invoking Post with HttpClient using a Client Certificate results in “The client certificate credentials were not recognized”