關於iOS10中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
為YES
來禁用 ATS,不過如果你這麼做的話,需要在提交 app 時進行說明,為什麼需要訪問非 HTTPS 內容。一般來說,可能類似瀏覽器類的 app 比較容易能通過。 -
相比於使用
NSAllowsArbitraryLoads
將全部 HTTP 內容開放,選擇使用NSExceptionDomains
來針對特定的域名開放 HTTP 應該要相對容易過稽核。“需要訪問的域名是第三方伺服器,他們沒有進行 HTTPS 對應”會是稽核時的一個可選理由,但是這應該只需要針對特定域名,而非全面開放。如果訪問的是自己的伺服器的話,可能這個理由會無法通過。 -
對於網頁瀏覽和視訊播放的行為,iOS 10 中新加入了
NSAllowsArbitraryLoadsInWebContent
鍵。通過將它設定為YES
,可以讓你的 app 中的WKWebView
和使用AVFoundation
播放的線上視訊不受 ATS 的限制。這也應該是絕大多數使用了相關特性的 app 的選擇。但是壞訊息是這個鍵在 iOS 9 中並不會起作用。
總結一下就是,對於 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
和NSAllowsArbitraryLoadsInWebContent
部分的描述作出的。如果您發現這個行為發生了變化,或者上面的列表存在問題,歡迎留言,我會進行更正。
關於 UIWebView
是否也可以在 NSAllowsArbitraryLoadsInWebContent
為 YES
時訪問 HTTP,Apple 內部似乎也在爭論,但是個人認為是時候淘汰 UIWebView
了。如果沒有特殊的什麼需求的話,儘早將 UIWebView
全部換為 WkWebView
會是明智的選擇。
不得不說,Apple 使用自己現在的強勢地位,在推動技術進步上的做的努力是有目共睹的。不論是前幾天強制支援 IPv6,還是現在的 HTTPS,其實都不是很容易就能作出的決定。而為使用者構建一個更安全的使用環境,可能不僅是 Apple 單方面可以做的,也是需要開發者來配合的一件事情。儘快適配更進步和安全的使用方式,會是一件雙贏的事情。
相關文章
- 關於 iOS 10 中 ATS 的問題iOS
- 關於工作中遇到的問題
- 關於cuda中的函式問題函式
- 關於struts中html:errors/的問題HTMLError
- 關於 mysql 中的 rand () 查詢問題MySql
- 關於 Laravel 中 Ajax 問題的小結Laravel
- java中關於Map的九大問題Java
- 關於考勤模組中設計的問題
- 關於jsp中轉發的問題JS
- 急問:關於servlet中得session問題ServletSession
- Elasticsearch中關於transform的一個問題分析ElasticsearchORM
- 關於頁面中彈窗的定位問題
- 關於QGraphicsView中的物件移動問題. zView物件
- 關於mysql中limit最佳化的問題MySqlMIT
- 新手關於jbuilder中除錯session的問題UI除錯Session
- [求助]關於Appfuse中Form的scope問題APPORM
- 關於python中填充缺失值的問題Python
- 關於字串中取相同的字元問題(小學題)字串字元
- 關於SQLServerDriver的問題SQLServer
- 關於 JavaMail 的問題JavaAI
- 關於session的問題Session
- 關於Swift中的泛函式find的問題Swift函式
- 關於angular的$resource中的isArray屬性問題Angular
- 關於Action中的setAttribute,和session的問題!!!!Session
- 關於SSH中對於action的監聽問題(關於系統計數)
- Java中關於二分查詢的問題Java
- 關於Delphi中TRttiContext.FindType失效的問題Context
- 關於oracle中blob欄位的錄入問題Oracle
- 請教關於Jive中過濾器的問題過濾器
- 關於jQuery radio 選中失效的問題jQuery
- 關於spring框架中的事務問題(急)Spring框架
- 關於CSS中的float可能出現的小問題CSS
- 關於學習java中的按位取反(~)的問題Java
- 關於配置檔案中的預設值的問題
- 關於javascript的this指向問題JavaScript
- 關於跨域的問題跨域
- 關於bit code的問題
- 關於序列同步的問題