首先是服务器端: 有一个内部可达的apache服务器,有几个虚拟主机。 对于http(sans'!)请求,我使用IP作为URL,并在Host-Headerfield中添加主机名。
这很有效。
但是当我建立SSL连接时,我遇到的问题似乎与SNI有关。
我发现了这个Overriding TLS Chain Validation Correctly并在我的代码中实现了它。
所以我更新了信任
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
但我仍然从服务器获得400。
更新
URLSession
确实支持SNI,但我的问题是我需要添加其他内容或更改hostname
中的SSLHandshake
。
首先是服务器的简短描述: 服务器是一个Apache服务器,只能通过IP访问,但它有多个vhost,可以通过主机名在本地使用,但当我从外部设备(如iPhone)连接到它时,我必须在{添加vhost的主机名{1}}。
所以我的工作是:我使用基于IP的URL创建URLRequest,然后添加带有主机名的Host-Headerfield
Headerfield
HOST
这适用于非安全的http-Requests,但是一旦使用https,服务器就会返回" 400 Bad request"并且http-ssl-error.log包含以下错误:
if let url = URL("https://192.168.178.54:8890") {
var request = URLRequest(url: url)
request.addValue("foobar:8890", forHTTPHeaderField: "Host")
…
}
这是因为默认情况下,SSLHandshake使用URL中提供的值,在我的例子中,这是IP。
我现在试图弄清楚如何在SSLHandshake中提供不同的主机名,或者提供类似自己的DNS解析器的东西,我仍然可以使用基于主机名的URL,但iOS可以直接获得路由。 / p>
答案 0 :(得分:0)
首先,我们是如何解决它的:服务器专家最终正确地完成了他们的工作,并且没有搞乱设备设置。
返回,我也将我的问题发布在Apple Dev Forums
我也从我的TSI收到了此消息:
将您的事件转移给了我,因为我通常都领导 DTS中的NSURLSession和TLS问题(我当时不在办公室时 您的事件最初是来的。
回到您的技术问题,看来我已经回复了您 通过为此创建的DevForums线程。
https://forums.developer.apple.com/thread/82179
该回复相当简短,但确实涵盖了要点:
无法在NSURLSession级别配置SNI名称
我建议的替代方法是使用
.local
DNS名称如上所述,我的DevForums响应非常简短,因此如果您有 关于后者的任何后续问题,我很乐意回答 在这里。
您可以/可以/在网络的较低级别覆盖SNI名称 堆栈,即CFSocketStream(通过NSSStream和 CFStream API)和安全传输。理论上你可以实现 您的NSURLProtocol子类中您自己的HTTP协议层,使用 这些API用于TLS-over-TCP方面,但我/ strong / 建议不要这样做,因为这需要大量工作。
分享并享受 -奎因《爱斯基摩人!》 Apple开发人员关系,开发人员技术支持,核心操作系统/硬件