客户端证书"The request was aborted: Could not create SSL/TLS secure channel"



几年前,我设法使我们的代码包含一个客户端证书。(参见Elasticsearch NEST HttpClientHandler证书的最后一篇文章)。我试图在另一个项目中使用相同的代码,但它失败了:

"ExceptionMessage": "The request was aborted: Could not create SSL/TLS secure channel."

大多数建议都围绕设置ServicePointManager。安全协议= Tls12;我已经试过了所有的组合。

我试图缩小范围,只是添加了

直接使用HttpClientHandler

示例来自https://damienbod.com/2019/09/07/using-certificate-authentication-with-ihttpclientfactory-and-httpclient/

private async Task<JsonDocument> GetApiDataUsingHttpClientHandler()
{
var cert = new X509Certificate2(Path.Combine(_environment.ContentRootPath, "sts_dev_cert.pfx"), "1234");
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(cert);
var client = new HttpClient(handler);

var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://localhost:44379/api/values"),
Method = HttpMethod.Get,
};
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
var data = JsonDocument.Parse(responseContent);
return data;
}

throw new ApplicationException($"Status code: {response.StatusCode}, Error: {response.ReasonPhrase}");
}

这在一个方法中完成了所有的事情(读取证书,附加到处理程序,并发出请求)。如果我在一个独立的项目中运行这段代码,它可以正常工作。我试图从服务结构中托管的WebApi运行它。在调试时,我可以看到获得了证书并正确地添加到处理程序中。调用从来没有离开我的代码(即从未发出)与Fiddler验证。

我们在Service Fabric的另一个解决方案中做了同样的事情,并且一切正常。

还有什么可能被遗漏的吗?

谢谢!

注:添加完整异常

{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred while sending the request.",
"ExceptionType": "System.Net.Http.HttpRequestException",
"StackTrace": "   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Net.Http.HttpClient.<FinishSendAsyncBuffered>d__58.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext()rn--- End of stack trace from previous location where exception was thrown ---rn   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()rn   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "The request was aborted: Could not create SSL/TLS secure channel.",
"ExceptionType": "System.Net.WebException",
"StackTrace": "   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)rn   at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)"
}
}

通过比较我们的两个解决方案,我发现了一些解决方案。我不知道这到底是怎么回事,但确实管用。我认为它需要某种用户上下文来打开通道。

在Service Fabric项目的AppManifest.xml中,我在底部添加了这段代码:

<Principals>
<Users>
<User Name="SomeUserName">
<MemberOf>
<SystemGroup Name="Administrators" />
</MemberOf>
</User>
</Users>
</Principals>
<Policies>
<DefaultRunAsPolicy UserRef="SomeUserName" />
</Policies>

注意"SomeUserName"实际上不对应于我系统上的任何用户帐户。也许它正在内存中创建一个用户上下文。

相关内容

  • 没有找到相关文章

最新更新