關(guān)于 iOS 10 中 ATS 的問題
本文于 2016 年 11 月 28 日按照 Apple 最新的文檔和 Xcode 8 中的表現(xiàn)進(jìn)行了部分更新动羽。
WWDC 15 提出的 ATS (App Transport Security) 是 Apple 在推進(jìn)網(wǎng)絡(luò)通訊安全的一個(gè)重要方式默勾。在 iOS 9 和 OS X 10.11 中,默認(rèn)情況下非 HTTPS 的網(wǎng)絡(luò)訪問是被禁止的裹芝。當(dāng)然檬输,因?yàn)檫@樣的推進(jìn)影響面非常廣弟跑,作為緩沖廊蜒,我們可以在 Info.plist 中添加NSAppTransportSecurity字典并且將NSAllowsArbitraryLoads設(shè)置為YES來禁用 ATS添寺。相信大家都已經(jīng)對(duì)這個(gè)非常熟悉了胯盯,因?yàn)槲易约阂簿S護(hù)了一些網(wǎng)絡(luò)相關(guān)的框架,所以我還自己準(zhǔn)備了一個(gè)小腳本來快速關(guān)閉 ATS计露。
不過博脑,WWDC 16 中,Apple 表示將繼續(xù)在 iOS 10 和 macOS 10.12 里收緊對(duì)普通 HTTP 的訪問限制票罐。從 2017 年 1 月 1 日起叉趣,所有的新提交 app 默認(rèn)是不允許使用NSAllowsArbitraryLoads來繞過 ATS 限制的,也就是說该押,我們最好保證 app 的所有網(wǎng)絡(luò)請(qǐng)求都是 HTTPS 加密的疗杉,否則可能會(huì)在應(yīng)用審核時(shí)遇到麻煩。
現(xiàn)在 (2016-11-28)蚕礼,這方面的相關(guān)規(guī)定和幾個(gè)事實(shí)如下:
默認(rèn)情況下你的 app 可以訪問加密足夠強(qiáng) (TLSv1.2 以上烟具,AES-128 和 SHA-2 以及 ECDHC 等) 的 HTTPS 內(nèi)容。這對(duì)所有的網(wǎng)絡(luò)請(qǐng)求都有效奠蹬,包括NSURLSession朝聋,通過 AVFoundation 訪問的流媒體,UIWebView以及WKWebView等囤躁。
你依然可以添加NSAllowsArbitraryLoads為YES來全面禁用 ATS冀痕,不過如果你這么做的話荔睹,需要在提交 app 時(shí)進(jìn)行說明,為什么需要訪問非 HTTPS 內(nèi)容言蛇。一般來說僻他,可能簡(jiǎn)單粗暴地開啟這個(gè)選項(xiàng),而又無法找到正當(dāng)理由的 app 會(huì)難以通過審核腊尚。
相比于使用NSAllowsArbitraryLoads將全部 HTTP 內(nèi)容開放吨拗,選擇使用NSExceptionDomains來針對(duì)特定的域名,通過設(shè)定該域名下的NSExceptionAllowsInsecureHTTPLoads來開放 HTTP 應(yīng)該要相對(duì)容易過審核跟伏《撸“需要訪問的域名是第三方服務(wù)器,他們沒有進(jìn)行 HTTPS 對(duì)應(yīng)”會(huì)是審核時(shí)的一個(gè)可選理由受扳,但是這應(yīng)該只需要針對(duì)特定域名携龟,而非全面開放。如果訪問的是自己的服務(wù)器的話勘高,可能這個(gè)理由會(huì)無法通過峡蟋。
對(duì)于網(wǎng)頁瀏覽和視頻播放的行為,iOS 10 中新加入了NSAllowsArbitraryLoadsInWebContent和NSAllowsArbitraryLoadsForMedia鍵华望。通過將它們?cè)O(shè)置為YES蕊蝗,可以讓你的 app 中的UIWebView、WKWebView或者使用AVFoundation播放的在線視頻不受 ATS 的限制赖舟。雖然依然需要在審核時(shí)進(jìn)行說明蓬戚,但這也應(yīng)該是絕大多數(shù)使用了相關(guān)特性的 app 的首選。壞消息是這個(gè)鍵在 iOS 9 中并不會(huì)起作用宾抓。
總結(jié)一下就是以下兩點(diǎn):
對(duì)于 API 請(qǐng)求子漩,基本上是必須使用 HTTPS 的,特別是如果你們自己可以管理服務(wù)器的話石洗〈逼茫可能需要后端的同學(xué)盡快升級(jí)到 HTTPS (不過話說雖然是用 Let's Encrypt 的,我一個(gè)個(gè)人博客都啟用 HTTPS 了讲衫,作為 API 的用戶服務(wù)器缕棵,還不開 HTTPS 真有點(diǎn)說不過去)。如果使用的是第三方的 API涉兽,而他們沒有提供 HTTPS 支持的話招驴,需要在NSExceptionDomains中進(jìn)行添加。
如果你的 app 只支持 iOS 10枷畏,并且有用戶可以自由輸入網(wǎng)址進(jìn)行瀏覽的功能忽匈,或者是在線視頻音頻播放功能的話,只加入NSAllowsArbitraryLoadsInWebContent或/和NSAllowsArbitraryLoadsForMedia矿辽,并且將組件換成UIWebView或WKWebView丹允,以及AVFoundation中的 player 就可以了。如果你還需要支持 iOS 9袋倔,并且需要訪問網(wǎng)頁和視頻的話雕蔽,可能只能去開啟NSAllowsArbitraryLoads然后提交時(shí)進(jìn)行說明,并且看 Apple 審核員的臉色決定讓不讓通過了宾娜。除了WKWebKit以外批狐,另外一個(gè)訪問網(wǎng)頁的選擇是使用SFSafariViewController。因?yàn)槠鋵?shí)SFSafariViewController就是一個(gè)獨(dú)立于 app 的 Safari 進(jìn)程前塔,所以它完全不受 ATS 的限制嚣艇。
如果你需要使用內(nèi)網(wǎng),可以設(shè)置NSAllowsLocalNetworking华弓,而不必?fù)?dān)心 SSL 連接的問題食零。
另外,當(dāng)NSAllowsArbitraryLoads和NSAllowsArbitraryLoadsInWebContent或NSAllowsArbitraryLoadsForMedia同時(shí)存在時(shí)寂屏,根據(jù)系統(tǒng)不同贰谣,表現(xiàn)的行為也會(huì)不一樣。簡(jiǎn)單說迁霎,iOS 9 只看NSAllowsArbitraryLoads吱抚,而 iOS 10 會(huì)優(yōu)先看InWebContent和ForMedia的部分。在 iOS 10 中考廉,要是后兩者存在的話秘豹,在相關(guān)部分就會(huì)忽略掉NSAllowsArbitraryLoads;如果不存在昌粤,則遵循NSAllowsArbitraryLoads的設(shè)定既绕。說起來可能有點(diǎn)復(fù)雜,我在這里總結(jié)了一下根據(jù)NSAppTransportSecurity中設(shè)定條件不同婚苹,所對(duì)應(yīng)的系統(tǒng)版本和請(qǐng)求組件的行為的不同岸更,可以作為你設(shè)置這個(gè)字典時(shí)的參考 (表中使用了NSAllowsArbitraryLoadsInWebContent作為例子,NSAllowsArbitraryLoadsForMedia也同理):
ATS 設(shè)定使用的組件iOS 9 HTTPiOS 10 HTTP備注
NSAllowsArbitraryLoads: NOWebView??默認(rèn)行為
URLSession??
NSAllowsArbitraryLoads: YESWebView??徹底禁用 ATS
URLSession??審核時(shí)需要說明理由
NSAllowsArbitraryLoads: NO & NSAllowsArbitraryLoadsInWebContent: YESWebView??只對(duì)網(wǎng)頁內(nèi)容禁用 ATS
URLSession??保證 API 的安全性
NSAllowsArbitraryLoads: NO & NSAllowsArbitraryLoadsInWebContent: NOWebView??
URLSession??
NSAllowsArbitraryLoads: YES & NSAllowsArbitraryLoadsInWebContent: NOWebView??對(duì)于 iOS 10膊升,NSAllowsArbitraryLoadsInWebContent 存在時(shí)忽略 NSAllowsArbitraryLoads 的設(shè)置
URLSession??iOS 9 將繼續(xù)使用 NSAllowsArbitraryLoads
NSAllowsArbitraryLoads: YES & NSAllowsArbitraryLoadsInWebContent: YESWebView??對(duì)于 iOS 10怎炊,NSAllowsArbitraryLoadsInWebContent 存在時(shí)忽略 NSAllowsArbitraryLoads 的設(shè)置
URLSession??iOS 9 將繼續(xù)使用 NSAllowsArbitraryLoads
該列表是根據(jù) Apple prerelease 的文檔中關(guān)于NSAppTransportSecurity和NSAllowsArbitraryLoadsInWebContent部分的描述作出的。如果您發(fā)現(xiàn)這個(gè)行為發(fā)生了變化廓译,或者上面的列表存在問題评肆,歡迎留言,我會(huì)進(jìn)行更正非区。
作為參考瓜挽,這里將有效的NSAppTransportSecurity字典結(jié)構(gòu)也一并附上:
NSAppTransportSecurity : Dictionary {? ? NSAllowsArbitraryLoads :BooleanNSAllowsArbitraryLoadsForMedia :BooleanNSAllowsArbitraryLoadsInWebContent :BooleanNSAllowsLocalNetworking :BooleanNSExceptionDomains : Dictionary {: Dictionary {? ? ? ? ? ? NSIncludesSubdomains : Boolean? ? ? ? ? ? NSExceptionAllowsInsecureHTTPLoads : Boolean? ? ? ? ? ? NSExceptionMinimumTLSVersion : String? ? ? ? ? ? NSExceptionRequiresForwardSecrecy : Boolean? // Default value is YES? ? ? ? ? ? NSRequiresCertificateTransparency : Boolean? ? ? ? }? ? }}
不得不說,Apple 使用自己現(xiàn)在的強(qiáng)勢(shì)地位征绸,在推動(dòng)技術(shù)進(jìn)步上的做的努力是有目共睹的久橙。不論是前幾天強(qiáng)制支持 IPv6俄占,還是現(xiàn)在的 HTTPS,其實(shí)都不是很容易就能作出的決定淆衷。而為用戶構(gòu)建一個(gè)更安全的使用環(huán)境缸榄,可能不僅是 Apple 單方面可以做的,也是需要開發(fā)者來配合的一件事情祝拯。盡快適配更進(jìn)步和安全的使用方式甚带,會(huì)是一件雙贏的事情。
以此文章來加入Toptal移動(dòng)應(yīng)用自由職業(yè)者群組佳头。