您的位置:首页 > 移动开发 > IOS开发

关于 iOS 10 中 ATS 的问题

2017-05-24 13:36 309 查看


本文于 2016 年 11 月 28 日按照 Apple 最新的文档和 Xcode 8 中的表现进行了部分更新。

WWDC 15 提出的 ATS (App Transport Security) 是 Apple 在推进网络通讯安全的一个重要方式。在 iOS 9 和 OS X 10.11 中,默认情况下非 HTTPS 的网络访问是被禁止的。当然,因为这样的推进影响面非常广,作为缓冲,我们可以在 Info.plist 中添加 
NSAppTransportSecurity
 字典并且将 
NSAllowsArbitraryLoads
 设置为 
YES
 来禁用
ATS。相信大家都已经对这个非常熟悉了,因为我自己也维护了一些网络相关的框架,所以我还自己准备了一个小脚本来快速关闭
ATS。

不过,WWDC 16 中,Apple 表示将继续在 iOS 10 和 macOS 10.12 里收紧对普通 HTTP 的访问限制。从 2017 年 1 月 1 日起,所有的新提交 app 默认是不允许使用 
NSAllowsArbitraryLoads
 来绕过
ATS 限制的,也就是说,我们最好保证 app 的所有网络请求都是 HTTPS 加密的,否则可能会在应用审核时遇到麻烦。

现在 (2016-11-28),这方面的相关规定和几个事实如下:

默认情况下你的 app 可以访问加密足够强 (TLS v1.2
以上,AES-128 和 SHA-2 以及 ECDHC 等) 的 HTTPS 内容。这对所有的网络请求都有效,包括 
NSURLSession
,通过
AVFoundation 访问的流媒体,
UIWebView
 以及 
WKWebView
 等。

你依然可以添加 
NSAllowsArbitraryLoads
 为 
YES
 来全面禁用
ATS,不过如果你这么做的话,需要在提交 app 时进行说明,为什么需要访问非 HTTPS 内容。一般来说,可能简单粗暴地开启这个选项,而又无法找到正当理由的 app 会难以通过审核。

相比于使用 
NSAllowsArbitraryLoads
 将全部
HTTP 内容开放,选择使用 
NSExceptionDomains
 来针对特定的域名,通过设定该域名下的 
NSExceptionAllowsInsecureHTTPLoads
 来开放
HTTP 应该要相对容易过审核。“需要访问的域名是第三方服务器,他们没有进行 HTTPS 对应”会是审核时的一个可选理由,但是这应该只需要针对特定域名,而非全面开放。如果访问的是自己的服务器的话,可能这个理由会无法通过。

对于网页浏览和视频播放的行为,iOS 10 中新加入了 
NSAllowsArbitraryLoadsInWebContent
 和 
NSAllowsArbitraryLoadsForMedia
 键。通过将它们设置为 
YES
,可以让你的
app 中的 
UIWebView
WKWebView
或者使用 
AVFoundation
 播放的在线视频不受
ATS 的限制。虽然依然需要在审核时进行说明,但这也应该是绝大多数使用了相关特性的 app 的首选。坏消息是这个键在 iOS 9 中并不会起作用。

总结一下就是以下两点:

对于 API 请求,基本上是必须使用 HTTPS 的,特别是如果你们自己可以管理服务器的话。可能需要后端的同学尽快升级到 HTTPS (不过话说虽然是用 Let’s Encrypt 的,我一个个人博客都启用 HTTPS 了,作为 API 的用户服务器,还不开 HTTPS 真有点说不过去)。如果使用的是第三方的 API,而他们没有提供 HTTPS 支持的话,需要在 
NSExceptionDomains
 中进行添加。

如果你的 app 只支持 iOS 10,并且有用户可以自由输入网址进行浏览的功能,或者是在线视频音频播放功能的话,只加入 
NSAllowsArbitraryLoadsInWebContent
 或/和 
NSAllowsArbitraryLoadsForMedia
,并且将组件换成 
UIWebView
 或 
WKWebView
,以及 
AVFoundation
 中的
player 就可以了。如果你还需要支持 iOS 9,并且需要访问网页和视频的话,可能只能去开启 
NSAllowsArbitraryLoads
 然后提交时进行说明,并且看
Apple 审核员的脸色决定让不让通过了。除了 
WKWebKit
 以外,另外一个访问网页的选择是使用 
SFSafariViewController
。因为其实 
SFSafariViewController
 就是一个独立于
app 的 Safari 进程,所以它完全不受 ATS 的限制。

如果你需要使用内网,可以设置 
NSAllowsLocalNetworking
,而不必担心
SSL 连接的问题。

另外,当 
NSAllowsArbitraryLoads
 和 
NSAllowsArbitraryLoadsInWebContent
 或 
NSAllowsArbitraryLoadsForMedia
 同时存在时,根据系统不同,表现的行为也会不一样。简单说,iOS
9 只看 
NSAllowsArbitraryLoads
,而
iOS 10 会优先看 
InWebContent
 和 
ForMedia
 的部分。在
iOS 10 中,要是后两者存在的话,在相关部分就会忽略掉 
NSAllowsArbitraryLoads
;如果不存在,则遵循 
NSAllowsArbitraryLoads
 的设定。说起来可能有点复杂,我在这里总结了一下根据 
NSAppTransportSecurity
 中设定条件不同,所对应的系统版本和请求组件的行为的不同,可以作为你设置这个字典时的参考
(表中使用了 
NSAllowsArbitraryLoadsInWebContent
 作为例子,
NSAllowsArbitraryLoadsForMedia
 也同理):
ATS 设定使用的组件iOS 9 HTTPiOS 10 HTTP备注
NSAllowsArbitraryLoads: NOWebView默认行为
 URLSession 
NSAllowsArbitraryLoads: YESWebView彻底禁用 ATS
 URLSession审核时需要说明理由
NSAllowsArbitraryLoads: NO & NSAllowsArbitraryLoadsInWebContent: YESWebView只对网页内容禁用 ATS
 URLSession保证 API 的安全性
NSAllowsArbitraryLoads: NO & NSAllowsArbitraryLoadsInWebContent: NOWebView 
 URLSession 
NSAllowsArbitraryLoads: YES & NSAllowsArbitraryLoadsInWebContent: NOWebView对于 iOS 10,NSAllowsArbitraryLoadsInWebContent 存在时忽略 NSAllowsArbitraryLoads 的设置
 URLSessioniOS 9 将继续使用 NSAllowsArbitraryLoads
NSAllowsArbitraryLoads: YES & NSAllowsArbitraryLoadsInWebContent: YESWebView对于 iOS 10,NSAllowsArbitraryLoadsInWebContent 存在时忽略 NSAllowsArbitraryLoads 的设置
 URLSessioniOS 9 将继续使用 NSAllowsArbitraryLoads
该列表是根据 Apple prerelease 的文档中关于 
NSAppTransportSecurity
 和 
NSAllowsArbitraryLoadsInWebContent
 部分的描述作出的。如果您发现这个行为发生了变化,或者上面的列表存在问题,欢迎留言,我会进行更正。

作为参考,这里将有效的 
NSAppTransportSecurity
 字典结构也一并附上:

NSAppTransportSecurity : Dictionary {
NSAllowsArbitraryLoads : Boolean
NSAllowsArbitraryLoadsForMedia : Boolean
NSAllowsArbitraryLoadsInWebContent : Boolean
NSAllowsLocalNetworking : Boolean
NSExceptionDomains : Dictionary {
<domain-name-string> : Dictionary {
NSIncludesSubdomains : Boolean
NSExceptionAllowsInsecureHTTPLoads : Boolean
NSExceptionMinimumTLSVersion : String
NSExceptionRequiresForwardSecrecy : Boolean   // Default value is YES
NSRequiresCertificateTransparency : Boolean
}
}
}


不得不说,Apple 使用自己现在的强势地位,在推动技术进步上的做的努力是有目共睹的。不论是前几天强制支持 IPv6,还是现在的 HTTPS,其实都不是很容易就能作出的决定。而为用户构建一个更安全的使用环境,可能不仅是 Apple 单方面可以做的,也是需要开发者来配合的一件事情。尽快适配更进步和安全的使用方式,会是一件双赢的事情。

转自:王巍的博客:https://onevcat.com/2016/06/ios-10-ats/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: