原文連接配接:https://onevcat.com/2016/06/ios-10-ats/
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 年 6 月 17 日),這方面的相關規定和幾個事實如下。但是似乎 Apple 安全部門對現在的情況也有些内部沖突,是以不排除在正式版中發生改變的可能性。我也會對此繼續關注,并在需要的時候對本文進行更新。如果您發現了下面所述和事實不符的話,也歡迎留言提出,我會進行修正。
- 預設情況下你的 app 可以通路加密足夠強 (TLS v1.2 以上,AES-128 和 SHA-2 以及 ECDHC 等) 的 HTTPS 内容。這對所有的網絡請求都有效,包括
,NSURLSession
以及UIWebView
等。WKWebView
- 你依然可以添加
為NSAllowsArbitraryLoads
來禁用 ATS,不過如果你這麼做的話,需要在送出 app 時進行說明,為什麼需要通路非 HTTPS 内容。一般來說,可能類似浏覽器類的 app 比較容易能通過。YES
- 相比于使用
将全部 HTTP 内容開放,選擇使用NSAllowsArbitraryLoads
來針對特定的域名開放 HTTP 應該要相對容易過稽核。“需要通路的域名是第三方伺服器,他們沒有進行 HTTPS 對應”會是稽核時的一個可選理由,但是這應該隻需要針對特定域名,而非全面開放。如果通路的是自己的伺服器的話,可能這個理由會無法通過。NSExceptionDomains
- 對于網頁浏覽和視訊播放的行為,iOS 10 中新加入了
鍵。通過将它設定為NSAllowsArbitraryLoadsInWebContent
,可以讓你的 app 中的YES
和使用WKWebView
播放的線上視訊不受 ATS 的限制。這也應該是絕大多數使用了相關特性的 app 的選擇。但是壞消息是這個鍵在 iOS 9 中并不會起作用。AVFoundation
總結一下就是,對于 API 請求,基本上是必須使用 HTTPS 的,特别是如果你們自己可以管理伺服器的話。可能需要後端的同學盡快更新到 HTTPS (不過話說雖然是用 Let's Encrypt 的,我一個個人部落格都啟用 HTTPS 了,作為 API 的使用者伺服器,還不開 HTTPS 真有點說不過去)。如果你的 app 隻支援 iOS 10,并且有使用者可以自由輸入網址進行浏覽的功能,或者是線上視訊音頻播放功能的話,簡單地加入
NSAllowsArbitraryLoadsInWebContent
,并且将元件換成
WKWebKit
或者
AVFoundation
就可以了。如果你還需要支援 iOS 9,并且需要通路網頁和視訊的話,可能隻能去開啟
NSAllowsArbitraryLoads
然後送出時進行說明,并且看 Apple 稽核員的臉色決定讓不讓通過了。除了
WKWebKit
以外,另外一個通路網頁的選擇是使用
SFSafariViewController
。因為其實
SFSafariViewController
就是一個獨立于 app 的 Safari 程序,是以它完全不受 ATS 的限制。
另外,當
NSAllowsArbitraryLoads
和
NSAllowsArbitraryLoadsInWebContent
同時存在時,根據系統不同,表現的行為也會不一樣。簡單說,iOS 9 隻看
NSAllowsArbitraryLoads
,而 iOS 10 會先看
NSAllowsArbitraryLoadsInWebContent
。在 iOS 10 中,要是
NSAllowsArbitraryLoadsInWebContent
存在的話,就忽略掉
NSAllowsArbitraryLoads
,如果它不存在,則遵循
NSAllowsArbitraryLoads
的設定。說起來可能有點複雜,我在這裡總結了一下根據
NSAppTransportSecurity
中設定條件不同,所對應的系統版本和請求元件的行為的不同,可以作為你設定這個字典時的參考。
ATS 設定 | 使用的元件 | iOS 9 HTTP | iOS 10 HTTP | 備注 |
---|---|---|---|---|
NSAllowsArbitraryLoads: NO | UIWebView | ❌ | ❌ | |
WKWebView | ❌ | ❌ | 預設行為 | |
URLSession | ❌ | ❌ | ||
NSAllowsArbitraryLoads: YES | UIWebView | ✅ | ✅ | 禁用 ATS |
WKWebView | ✅ | ✅ | 稽核時需要說明理由 | |
URLSession | ✅ | ✅ | ||
NSAllowsArbitraryLoads: NO & NSAllowsArbitraryLoadsInWebContent: YES | UIWebView | ❌ | ❌ | 隻對網頁内容禁用 ATS |
WKWebView | ❌ | ✅ | 對于大多數 app 的推薦做法, | |
URLSession | ❌ | ❌ | 保證安全性 | |
NSAllowsArbitraryLoads: NO & NSAllowsArbitraryLoadsInWebContent: NO | UIWebView | ❌ | ❌ | |
WKWebView | ❌ | ❌ | ||
URLSession | ❌ | ❌ | ||
NSAllowsArbitraryLoads: YES & NSAllowsArbitraryLoadsInWebContent: NO | UIWebView | ✅ | ❌ | 對于 iOS 10, |
WKWebView | ✅ | ❌ | NSAllowsArbitraryLoadsInWebContent 存在時忽略 NSAllowsArbitraryLoads 的設定 | |
URLSession | ✅ | ❌ | iOS 9 将繼續使用 NSAllowsArbitraryLoads | |
NSAllowsArbitraryLoads: YES & NSAllowsArbitraryLoadsInWebContent: YES | UIWebView | ✅ | ❌ | 對于 iOS 10, |
WKWebView | ✅ | ✅ | NSAllowsArbitraryLoadsInWebContent 存在時忽略 NSAllowsArbitraryLoads 的設定 | |
URLSession | ✅ | ❌ | iOS 9 将繼續使用 NSAllowsArbitraryLoads |
該清單是根據 Apple prerelease 的文檔中關于和
NSAppTransportSecurity
部分的描述作出的。現在 (2016.06.17) 的 iOS 10 beta 和 Xcode 8 beta 版本中
NSAllowsArbitraryLoadsInWebContent
似乎還不能正确工作。在現在的 beta 版中,似乎隻要存在
NSAllowsArbitraryLoadsInWebContent
,不論其設定如何,
NSAllowsArbitraryLoadsInWebContent
都不能加載。如果這個行為發生了變化,或者上面的清單存在問題,歡迎留言,我會進行更正。
WKWebView
關于
UIWebView
是否也可以在
NSAllowsArbitraryLoadsInWebContent
為
YES
時通路 HTTP,Apple 内部似乎也在争論,但是個人認為是時候淘汰
UIWebView
了。如果沒有特殊的什麼需求的話,盡早将
UIWebView
全部換為
WkWebView
會是明智的選擇。
不得不說,Apple 使用自己現在的強勢地位,在推動技術進步上的做的努力是有目共睹的。不論是前幾天強制支援 IPv6,還是現在的 HTTPS,其實都不是很容易就能作出的決定。而為使用者建構一個更安全的使用環境,可能不僅是 Apple 單方面可以做的,也是需要開發者來配合的一件事情。盡快适配更進步和安全的使用方式,會是一件雙赢的事情。
轉載于:https://www.cnblogs.com/sleepingSun/p/5850103.html