dko*_*ene 8 c# client-certificates azure x509certificate2 tls1.2
我遇到以下问题:我构建了一个应作为 Azure Web 服务运行的 Web 服务,它调用外部 API 检索一些数据。对于连接,外部公司向我提供了一个证书,我已成功将其存储在 Azure Keyvault 中。经过一番尝试和错误后,我在本地测试了下面的代码块,成功验证了证书是否已从保管库中成功检索。这导致我想要检索的数据得到成功响应。到目前为止一切顺利 - 直到我将其发布到 Azure。一切似乎工作正常,但是我收到以下错误消息:
从传输流接收到意外的 EOF 或 0 字节
我已经用完谷歌的前5页了。我不断寻找有关 TLS 的答案,但在测试选项时我明确将其设置为正确的版本(即使在这个代码片段中,我实际上也只使用 TLS 1.2 就很好)。
这是什么原因造成的?我是否缺少一些神秘的 Azure 配置设置?正如我所说,该代码在我的计算机上 100% 运行。问题似乎不是钥匙或金库。最大的区别是,我在本地以租户管理员身份运行代码,但是我为应用程序服务提供了托管身份,并具有对 keyvault 的正确权限。
我还将提供堆栈跟踪。var 结果 = 等待 client.GetAsync(url);
错误抛出于
var result = await client.GetAsync(url);
Run Code Online (Sandbox Code Playgroud)
我希望我已经提供了足够的信息。先感谢您
代码片段:
public async Task<string>GetData(string url) {
try {
var client = await GetHttpClient();
var result = await client.GetAsync(url);
if (result.IsSuccessStatusCode) {
var content = await result.Content.ReadAsStringAsync();
return content;
} else {
Exception ex = new Exception("Failed getting data: " + result.Content.ReadAsStringAsync().Result);
throw ex;
}
} catch (Exception ex) {
_telemetry.TrackException(ex);
throw;
}
}
public async Task<HttpClient> GetHttpClient() {
var cert = await GetCertFromVault();
var handler = new HttpClientHandler() {
ClientCertificateOptions = ClientCertificateOption.Manual,
SslProtocols = SslProtocols.Tls
| SslProtocols.Tls11
| SslProtocols.Tls12,
};
handler.ClientCertificates.Add(cert);
handler.ServerCertificateCustomValidationCallback = (message, certificate2, arg3, arg4) => true;
var client = new HttpClient(handler);
return client;
}
async Task<X509Certificate2> GetCertFromVault() {
try {
string keyVaultUrl = _configuration["KeyVault"];
string certKeyName = _configuration["CertKeyName"];
var cred = new DefaultAzureCredential();
//Get certificate as secret as to include the key:
var keyVaultClient = new SecretClient(new Uri(keyVaultUrl), cred);
var certResponse = await keyVaultClient.GetSecretAsync(certKeyName);
byte[] cert = System.Convert.FromBase64String(certResponse.Value.Value);
//Convert retrieved values to X509Certificate2
var resultKey = new X509Certificate2(cert, "", X509KeyStorageFlags.MachineKeySet
| X509KeyStorageFlags.PersistKeySet
| X509KeyStorageFlags.Exportable);
return resultKey;
} catch (Exception ex) {
_telemetry.TrackException(ex);
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
at System.Net.Security.SslStream.<FillHandshakeBufferAsync>g__InternalFillHandshakeBufferAsync|182_0[TIOAdapter](TIOAdapter adap, ValueTask`1 task, Int32 minSize)
at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsyncCore(Boolean async, Stream stream, SslClientAuthenticationOptions sslOptions, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.GetHttpConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsyncCore(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.SendAsyncCore(HttpRequestMessage request, HttpCompletionOption completionOption, Boolean async, Boolean emitTelemetryStartStop, CancellationToken cancellationToken)
at MyService.MyClient.GetData(String url) in [path]\MyClient.cs:line 40
Run Code Online (Sandbox Code Playgroud)
第 40 行对应于
var result = await client.GetAsync(url);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10227 次 |
| 最近记录: |