iOS 9 中使用客户端 SSL 证书并生成 HTTP 403 错误时的错误

Bug in iOS 9 when using client SSL certs and generating HTTP 403 errors

我认为我们刚刚在 iOS 9(2015 年 10 月 23 日的版本)上使用客户端 SSL 证书与后端 API 通信时发现了一个错误。与许多 REST 服务一样,我们的 API 生成 4xx 错误代码来传达状态。其中之一是当客户端尝试访问特定客户端 ID 无权访问的路径时出现 403 Forbidden 错误。请注意,此 HTTP 错误发生在客户端 SSL 证书已设置有效连接并且客户端 ID 已通过身份验证之后。

在iOS9中,这个序列会产生一个无效的客户端SSL错误:

FAILED: Error Domain=NSURLErrorDomain Code=-1206 "The server “our.server.here” requires a client certificate."

(注意:这是我的推文的跟进:https://twitter.com/ckmaresca/status/657576686318256128 - 我认为 SO 是大多数人会搜索的地方)

我们花了几天时间才最终弄清楚,但事实证明这个特定错误是由 Apple 的新应用程序传输层安全性产生的。具体来说,如果您正在使用客户端证书并且您的后端 API 生成 HTTP 403 错误,ATL 认为该证书是错误的并且会终止整个事务。

我们知道这一点,因为我们可以在服务器日志中看到请求通过并正确执行。我们还观察到套接字在请求期间保持活动状态,并且此错误仅在收到服务器响应后才会出现。我们也知道我们的客户端证书有效,因为任何不返回 403 的路径都可以零错误工作,并且将 HTTP 错误代码更改为 401 可以解决这个问题。

由于多种原因,这是有问题的,但主要是因为 HTTP 错误不是 SSL 错误。两者可以独立运行,使用有效的客户端 SSL 证书完全有可能出现 403 错误....

解决方法是将所有 403 错误更改为其他内容。我会注意到大量 Oauth1/2 服务器会生成各种 403 错误,因此这可能很重要。或者,可以使用反向代理将 HTTP 403 错误重新映射到不同的 HTTP 代码 - 我们尚未对此进行测试。

我们已经向 Apple 提交了一个错误,但我想提醒大家,这样也许他们就可以避免像我们一周那样用头撞墙....

感谢 Sherbit.io 工程团队(特别是 Varun 和 Matt)对此进行调试。