【发布时间】:2018-01-08 13:09:36
【问题描述】:
编辑 - 由于可能的误解: 这与 HTTP/2 的服务器端无关——它与来自旧服务器操作系统的客户端 HTTP/2 请求有关。另外,我使用 python (gobiko.apns) 让它工作,所以在我看来它应该是可能的。
编辑 2 这个问题似乎与 HTTP2 没有太大关系,而与苹果所需的密码有关。在 win10 之前的版本中,SslStream 不使用 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384。但是,由于它可以使用 python 来完成,所以在我看来它应该是可能的。任何帮助将不胜感激。
我们在这里和那里找到了一些代码来连接到在我们的开发环境中工作的 APNS。我们正在使用 .p8 证书并签署令牌作为授权(不是“旧”接口)。
这适用于我的开发电脑 (win10),但是当我将它传输到服务器 2008 R2 时,它会发出一个奇怪的警告。这似乎与 tls 连接的设置有关,但是,我对该区域不太熟悉。我真的搜索过,但我唯一能想到的是服务器 2008R2 由于密码或其他原因不支持它(这对我来说似乎不合理)。
在我的电脑上运行的代码(使用 nuget HttpTwo 和 Newtonsoft):
public static async void Send2(string jwt, string deviceToken)
{
var uri = new Uri($"https://{host}:443/3/device/{deviceToken}");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.ServerCertificateValidationCallback = delegate
{
Console.WriteLine("ServerCertificateValidationCallback");
return true;
};
string payloadData = Newtonsoft.Json.JsonConvert.SerializeObject(new
{
aps = new
{
alert = new
{
title = "hi",
body = "works"
}
}
});
//PayloadData always in UTF8 encoding
byte[] data = System.Text.Encoding.UTF8.GetBytes(payloadData);
var httpClient = new Http2Client(uri);
var headers = new NameValueCollection();
headers.Add("authorization", string.Format("bearer {0}", jwt));
headers.Add("apns-id", Guid.NewGuid().ToString());
headers.Add("apns-expiration", "0");
headers.Add("apns-priority", "10");
headers.Add("apns-topic", bundleId);
try
{
var responseMessage = await httpClient.Send(uri, HttpMethod.Post, headers, data);
if (responseMessage.Status == System.Net.HttpStatusCode.OK)
{
Console.WriteLine("Send Success");
return;
}
else
{
Console.WriteLine("failure {0}", responseMessage.Status);
return;
}
}
catch (Exception ex)
{
Console.WriteLine("ex");
Console.WriteLine(ex.ToString());
return;
}
}
正在投掷
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message received was unexpected or badly formatted
来自服务器 2008R2。
我还尝试了 WinHttpHandler,它也可以在我的 PC 上运行,但会抛出
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.WinHttpException: A security error occurred
Stacktraces 主要是异步的东西,但归结为 HttpTwo 实现的 HttpTwo.Http2Connection.<Connect> 和 WinHttpHandler 的 System.Net.Http.WinHttpHandler.<StartRequest>。
有什么我必须添加到服务器才能工作/我们可以让它工作吗?
更新 我在我的项目中包含了来自 HttpTwo 的源文件并对其进行了调试。异常发生在
await sslStream.AuthenticateAsClientAsync (
ConnectionSettings.Host,
ConnectionSettings.Certificates ?? new X509CertificateCollection (),
System.Security.Authentication.SslProtocols.Tls12,
false).ConfigureAwait (false);
在我的 Win8 测试电脑上。现在,当我在我自己的 PC 上仅使用主机参数的方法重载时,它会引发相同的异常,我猜是因为 tls 协议当时已关闭。
根据这个Github issue,它可能与密码有关。我之前在这方面遇到过一些问题,但在我看来,至少一台 WIN8 电脑必须能够同意足够安全的密码,对吧?
Schannel 抱怨“从远程端点收到了致命警报。TLS 协议定义的致命警报代码是 40。”,所以这也指向那个方向。
【问题讨论】:
-
据我所知,这个问题是关于 HTTP/2 的服务器端的——我的问题是关于在旧操作系统上运行的客户端实现。除此之外,HTTP/2 仍然是一个 tcp 实现,对吧?我认为 HttpTwo 应该能够运行客户端请求?但是,thnx,所以这意味着苹果强迫你使用“新”窗口操作系统?
-
我非常不同意 - 这可能是事后诸葛亮。我真的希望它会是其他的东西,比如在 servicepointmanager 上设置一些属性或其他东西。我之前也遇到过类似的问题,我确信 ServerVault 的超级用户会对这些问题做出同样的反应......
-
很抱歉,我无法向您说明清楚。我希望,一些成功连接到 APNS 的 C# 开发人员之前遇到过(并修复了)这个问题。我的问题实际上是关于:有什么我可以更改/添加以使我的代码正常工作。
-
@CamiloTerevinto,我不想让人讨厌——我真的需要找到答案:你说它永远不会在旧的 server2008R2 上工作。但是,我让它使用 Python 工作。 (gobiko.apns) 那怎么可能呢?
-
我不确定您为什么认为 Python 完全可以与 .NET 的实现方式相媲美。
标签: c# windows-server-2008 http2