你不知道的 Cocoa key — ATS (App Transport Security) 配置

2,455 阅读2分钟

ATS 简介

ATS 是 iOS 9 中引入的隐私设置功能。默认情况下,系统会为新应用启用该功能,并强制实施安全连接。如果直接进行 HTTP 请求会收到错误提示

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

在 iOS9 及以上的系统,默认会打开ATS,所以需要在 info.plist 中关掉 ATS。 修改完成的 info.plist 大概是这个样子:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>

应用

在接入 GoogleAdMob 时,按照谷歌的要求,对于 ATS 有如下的配置。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsForMedia</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>

新增了两个例外的情况 NSAllowsArbitraryLoadsForMedia,NSAllowsArbitraryLoadsInWebContent。查看开发者文档,这个两个 subkey 是从 iOS 10 开始引入的,可以更精细化的配置允许 HTTP 连接的例外情况。 一同引入的还有 NSRequiresCertificateTransparency 和 NSAllowsLocalNetworking。

在这里只简单的介绍一下谷歌要求添加的两个 key 的作用,其他的细节参考官方文档。

  • NSAllowsArbitraryLoadsForMedia, 默认值是 NO。如果设置为 YES,则会对于使用 AVFoundation 加载的媒体资源禁用 ATS 。

  • NSAllowsArbitraryLoadsInWebContent, 默认值为 NO。如果设置为 YES,则会对于使用 web view 发起的请求禁用 ATS。

这里可以看出谷歌的 ATS 配置是比较严谨的。对于iOS10及以上的系统,缩小了禁用 ATS 的范围。

下面画重点,在苹果开发者文档里有这么一段话

Version-specific ATS behavior: In a current operating system, the presence of a fine-grained transport security key (NSAllowsArbitraryLoadsForMedia, NSAllowsArbitraryLoadsInWebContent, or NSAllowsLocalNetworking) overrides the value of the NSAllowsArbitraryLoads key to NO. This allows you to set NSAllowsArbitraryLoads to YES if needed for your app in older operating systems, without disabling ATS generally in current operating systems.

简单的说就是,当你使用了这几个细粒度的ATS配置时(iOS10及以上系统),就会关掉 NSAllowsArbitraryLoads 这个力度很粗的开关(相当于忽略了该配置)。这就使得你可以在较老的系统上禁用 ATS(NSAllowsArbitraryLoads 设置为 YES),而在 iOS10 之后的系统上,不会禁用 ATS,只按照几个特例情况停用。

总结

按照谷歌的推荐配置会遇到的小问题就是,如果在工程中还有其他使用 HTTP 加载资源的情况(除了 AVFoundation 加载的媒体资源和 web view 发起的请求),那么就会收到最上面的错误提示。

解决办法也很简单,移除这两个细粒度的 ATS 配置。只需要将 NSAllowsArbitraryLoads 设置为 NO。

另一个解决办法,NSExceptionDomains 使用这个 key 来配置指定的域名,可以不受 NSAllowsArbitraryLoads 的限制。

参考资料:

Cocoa Keys