我的UWP應用連接到http(s)服務器以執行一些數據傳輸。 在建立TLS連接時,如果由於握手失敗而發生故障,HttpRequestMessage.TransportInformation會提供有關特定錯誤和服務器證書的信息,我們正在使用該信息將消息顯示給最終用戶。UWP HttpRequestMessage.TransportInformation丟失
上述所有工作都很好,直到我將開發機升級到Windows 10 build 1607並將應用程序重定向到「Windows 10 Anniversary Edition(10.0; Build 14393)」。早些時候這是「Windows 10(10.0; Build 10586)」。
在此更改之後,HttpRequestMessage.TransportInformation中的所有字段都爲空。但是,例外情況和相應的HRESULT會明確指出SSL錯誤(在此情況下不受信任的服務器證書)。
我試過使用StreamSocket,並且確實發生了SSL握手錯誤,但StreamSocket.Information屬性已經正確填寫了所有字段(服務器證書,錯誤等),因此可以檢查它們。
爲了記錄,服務器證書是自簽名的,並使用SHA1指紋/簽名算法。
在下面的代碼片段中,ConnectToServerHttpAsync中的req.TransprtInformation從不給服務器證書,而streamSock.Information在ConnectToServerAsync中提供服務器證書詳細信息。
問題:這是一個新的SDK中的錯誤,還是我必須做一些不同的與構建14393上的HttpClient獲取傳輸信息?沒有找到任何關於此行爲的MSDN或SO,因此張貼。
private async Task ConnectToServerHttpAsync(Uri connectUri)
{
HttpRequestMessage req = null;
try
{
using (HttpBaseProtocolFilter bpf = new HttpBaseProtocolFilter())
{
bpf.AllowUI = false;
using (HttpClient httpClient = new HttpClient(bpf))
{
req = new HttpRequestMessage(HttpMethod.Get, connectUri);
using (HttpResponseMessage res = await httpClient.SendRequestAsync(req))
{
Status = ((int)(res.StatusCode)) + " " + res.ReasonPhrase;
}
}
}
}
catch (Exception ex)
{
SocketErrorStatus eSocketErrorStatus = SocketError.GetStatus(ex.HResult);
Status = eSocketErrorStatus.ToString();
Status = req?.TransportInformation?.ServerCertificate?.ToString() ?? "No server certificate.";
}
req?.Dispose();
}
private async Task ConnectToServerAsync(Uri uriToConnect)
{
StreamSocket streamSock = new StreamSocket();
HostName hostName = new HostName(uriToConnect.Host);
try
{
await streamSock.ConnectAsync(hostName, uriToConnect.Port.ToString(), SocketProtectionLevel.Tls12);
Status = "Connected.";
streamSock.Dispose();
}
catch (Exception ex)
{
SocketErrorStatus eSocketErrorStatus = SocketError.GetStatus(ex.HResult);
Status = eSocketErrorStatus.ToString();
Status = "Certificate details:";
Status = "Friendly name: " + streamSock.Information.ServerCertificate.FriendlyName;
Status = "Issuer: " + streamSock.Information.ServerCertificate.Issuer;
Status = "SignatureAlgorithmName: " + streamSock.Information.ServerCertificate.SignatureAlgorithmName;
Status = "SignatureHashAlgorithmName: " + streamSock.Information.ServerCertificate.SignatureHashAlgorithmName;
Status = "Subject: " + streamSock.Information.ServerCertificate.Subject;
Status = "ValidFrom: " + streamSock.Information.ServerCertificate.ValidFrom.ToString();
Status = "ValidTo: " + streamSock.Information.ServerCertificate.ValidTo.ToString();
ServerCert = streamSock.Information.ServerCertificate;
}
}