macOS-Cocoa開發(fā)之沙盒機(jī)制及訪問Sandbox之外的文件

原文地址:http://www.skyfox.org/cocoa-macos-sandbox.html

iOS默認(rèn)并且只能讀寫對(duì)應(yīng)的沙盒目錄聂儒。

OSX自從10.6系統(tǒng)開始引入沙盒機(jī)制,規(guī)定發(fā)布到Mac AppStore的應(yīng)用,必須遵守沙盒約定。沙盒對(duì)應(yīng)用訪問的系統(tǒng)資源,硬件外設(shè),文件,網(wǎng)絡(luò),XPC,都做了嚴(yán)格的限制,這樣能防止惡意的App通過系統(tǒng)漏洞,攻擊系統(tǒng),獲取控制權(quán)限,保證了OSX系統(tǒng)的安全外驱。沙盒相當(dāng)于給每個(gè)App一個(gè)獨(dú)立的空間刻剥。要獲取自己空間之外的資源必須獲得授權(quán)遮咖。

macOS APP不需要上架的時(shí)候,可以不開啟Sandbox 功能造虏,可以隨意訪問mac上的文件御吞。

當(dāng)未開啟Sandbox功能上傳到APPStore的時(shí)候提示:

iTunes Store operation failed.
App sandbox not enabled. The following executables must include the "com.apple.security.app-sandbox" entitlement with a Boolean value of true in the entitlements property list: [( "org.skyfox.ProfilesTool.pkg/Payload/ProfilesTool.app/Contents/MacOS/ProfilesTool" )] Refer to App Sandbox page at https://developer.apple.com/devcenter/mac/app-sandbox/ for more information on sandboxing your app.

開啟Sandbox

App Sandbox

在Xcode工程target設(shè)置Tab的Capabilities中選擇 App Sandbox 為ON即可開啟使用沙盒,Xcode自動(dòng)生成.entitlements權(quán)限配置文件到工程漓藕。并且可以配置相應(yīng)的權(quán)限陶珠,(網(wǎng)絡(luò),硬件享钞,App Data揍诽,文件訪問)

Network:網(wǎng)絡(luò)訪問控制

Incoming Connections(Server) :應(yīng)用做為Server對(duì)外提供HTTP,FTP等服務(wù)時(shí)需要打開
Outgoing Connections(Client):做為客戶端,訪問服務(wù)器時(shí)需要打開

Hardware:硬件資源控, Printing為必須勾選栗竖。App的默認(rèn)第一個(gè)頂級(jí)菜單中有打印功能的子菜單:

Camera
Micophone
USB
Printing

App Data:獲取系統(tǒng)的聯(lián)系人暑脆,位置,日歷服務(wù)時(shí)需要打開:

Contacts
Location
Calendar

File Access:文件和用戶目錄的訪問控制,分為禁止none,只讀,讀寫3類:

User Selected File:文檔類應(yīng)用或者需要用戶選擇打開某個(gè)文件時(shí),需要選擇合適的訪問權(quán)限.
Downloads Folder
Pictures Folder
Music Folder
Movies Folder
如果應(yīng)用中不需要的權(quán)限項(xiàng)划滋,一律不要打開饵筑。否則App Review團(tuán)隊(duì)會(huì)拒絕你的應(yīng)用上架

entitlements權(quán)限配置信息存儲(chǔ)

沙盒中每個(gè)需要訪問權(quán)限的項(xiàng)都對(duì)應(yīng)一個(gè)key埃篓,對(duì)應(yīng)的value处坪,YES 或 NO表示是否允許訪問。選擇配置了沙盒的訪問控制信息后架专,Xcode會(huì)自動(dòng)保存到一個(gè)擴(kuò)展名為.entitlements的plist文件中



應(yīng)用打包時(shí)會(huì)對(duì)這個(gè)文件進(jìn)行簽名同窘, 應(yīng)用運(yùn)行期間要獲取某個(gè)權(quán)限時(shí),系統(tǒng)都會(huì)通過.entitlements去檢查應(yīng)用是否有授權(quán)部脚,如果沒有就拒絕訪問想邦。

Sandbox之外的文件怎么訪問?

那么問題就出現(xiàn)了委刘,開啟Sandbox 功能之后丧没,NSHomeDirectory對(duì)應(yīng)的文件夾形如:
/Users/yourName/Library/Containers/com.xxxx.appname/Data
程序數(shù)據(jù)文件的存儲(chǔ)路徑也不同,原來在
~/Library/Application Support/<app_name>/
如今在沙盒內(nèi):
~Library/Containers/<bundle_id>/Data/Library/Application/Support/<app_name>/
沙盒保證了程序只能訪問沙盒container下的文件夾锡移,這樣就相對(duì)安全的保護(hù)了程序自身呕童。

訪問沙盒外部文件

一、讓用戶人為選擇目錄

Capabilities中選擇 App Sandbox 淆珊,在File Access中User Selected File項(xiàng)中選擇Read/Write文件讀寫權(quán)限
沙盒有個(gè)默認(rèn)的規(guī)則夺饲。在App運(yùn)行期間通過NSOpenPanel用戶手動(dòng)打開的任意位置的文件,把這個(gè)這個(gè)路徑保存下來,后面都是可以直接用這個(gè)路徑繼續(xù)訪問獲取文件內(nèi)容的往声。
但是App重新啟動(dòng)后,這個(gè)文件路徑就不能直接訪問了擂找。要想永久的獲得應(yīng)用的Container目錄之外的文件,這里必須講一下Security-Scoped Bookmark。

Security-scoped bookmarks:

使用bookmarks之前同樣要在.entitlements文件中填寫對(duì)應(yīng)的key與value
Security-scoped bookmarks有2種:

1. An app-scoped bookmark

能為已沙盒程序提供對(duì)用戶指定文件和文件夾的持久訪問權(quán)浩销。 例如贯涎,如果程序采用了一個(gè)程序容器外的下載或處理目標(biāo)文件夾,通過 NSOpenpanel 對(duì)話框獲得用戶想使用該文件夾的初始訪問權(quán)慢洋。
然后柬采,為其創(chuàng)建一個(gè) app-scoped bookmark,將它作為程序的配置儲(chǔ)存(可能用屬性列 表文件或 NSUserDefaults 類)且警。有了 app-scoped bookmark粉捻,程序就能獲得對(duì)該文件夾的 未來訪問權(quán)了。這種bookmark方式使用的比較多斑芜。

在.entitlements文件對(duì)應(yīng)的key對(duì)應(yīng)的權(quán)限key為com.apple.security.files.bookmarks.app-scope

2. A document-scoped bookmark

提供了對(duì)特定文檔的持久訪問權(quán)肩刃。可以理解為針對(duì)文檔嵌套的一種權(quán)限模式杏头。比如你開發(fā)一個(gè)能編輯ppt文檔的應(yīng)用盈包,里面嵌入了視頻文件,圖片文件連接。那么下次打開這個(gè)ppt文檔時(shí)就能直接訪問這些文件而不需要在通過NSOpenPanel打開獲得授權(quán)醇王。

Document-scoped bookmark 只能指向文件而不是文件夾呢燥。并且這個(gè)文件必須不在系統(tǒng)使用的 位置上(如/private 或/Library)

在.entitlements文件對(duì)應(yīng)的key對(duì)應(yīng)的權(quán)限key為com.apple.security.files.bookmarks.document-scope

保存打開的文件URL的bookmark

獲取到URL的bookmarkData存儲(chǔ)到NSUserDefaults等位置
NSData *bookmarkData =[url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:NULL];

應(yīng)用啟動(dòng)時(shí)通過URL的bookmark獲取文件授權(quán)

通過bookmark數(shù)據(jù)解析獲取授權(quán)的NSURL,并且執(zhí)行startAccessingSecurityScopedResource方法得到訪問權(quán)限。

執(zhí)行block回調(diào)完成相關(guān)內(nèi)容讀取后,執(zhí)行stopAccessingSecurityScopedResource停止授權(quán)寓娩。

NSURL *allowedUrl = [NSURL URLByResolvingBookmarkData:bookmarkData options:NSURLBookmarkResolutionWithSecurityScope|NSURLBookmarkResolutionWithoutUI relativeToURL:nil bookmarkDataIsStale:&bookmarkDataIsStale error:NULL];
@try {
  [allowedUrl startAccessingSecurityScopedResource];
  block();
} @finally {
  [allowedUrl stopAccessingSecurityScopedResource];
}

二叛氨、文件訪問臨時(shí)例外

在開啟沙盒功能的App中,App僅可以訪問container中的數(shù)據(jù)棘伴,application groupcontainer寞埠,POSIX可讀的公開位置、用戶手動(dòng)Open或Save dialog打開的位置 焊夸。如果您的應(yīng)用程序需要永久訪問到其他位置仁连,你可以通過啟用本人所述的臨時(shí)例外entitlement權(quán)限鍵將額外的位置帶入你的沙盒
為每個(gè)您想要啟用訪問的路徑,將路徑指定為相應(yīng)的entitlement權(quán)限key值數(shù)組阱穗。每個(gè)字符串必須以斜杠 (/) 字符開頭 — — 它代表絕對(duì)路徑或相對(duì)于用戶的主目錄的路徑饭冬。如果您提供的是一個(gè)目錄路徑,你必須以斜杠字符串結(jié)束揪阶。

home-relative-path
臨時(shí)例外, 提供一個(gè)相對(duì)于user home目錄的路徑昌抠。相對(duì)于~

例如我指定“/Library/MobileDevice/Provisioning Profiles/”目錄用來讀取系統(tǒng)的profies文件。



當(dāng)我設(shè)置home相對(duì)路徑后遣钳,在程序中要手動(dòng)拼接上home目錄扰魂。

拼接home路徑有兩種方式:

一種是getpwuid方法

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <assert.h>

struct passwd *pw = getpwuid(getuid());
NSString *home =  [NSString stringWithUTF8String:pw->pw_dir];

一種是根據(jù)沙盒目錄字符串截取

 NSString *home = NSHomeDirectory();
    NSArray *pathArray = [home componentsSeparatedByString:@"/"];
    NSString *absolutePath;
    if ([pathArray count] > 2) {
        absolutePath = [NSString stringWithFormat:@"/%@/%@", [pathArray objectAtIndex:1], [pathArray objectAtIndex:2]];
    }

absolute-path
臨時(shí)例外, 提供一個(gè)絕對(duì)路徑麦乞。相對(duì)于 /

Entitlement key Capability
com.apple.security.temporary-exception.files.home-relative-path.read-only 開啟對(duì)于home指定子目錄或者文件的只讀權(quán)限
com.apple.security.temporary-exception.files.home-relative-path.read-write 開啟對(duì)于home指定子目錄或者文件的讀寫權(quán)限
com.apple.security.temporary-exception.files.absolute-path.read-only 開啟對(duì)于 / 指定子目錄或者文件的只讀權(quán)限
com.apple.security.temporary-exception.files.absolute-path.read-write 開啟對(duì)于 / 指定子目錄或者文件的讀寫權(quán)限
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市劝评,隨后出現(xiàn)的幾起案子姐直,更是在濱河造成了極大的恐慌,老刑警劉巖蒋畜,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件声畏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡姻成,警方通過查閱死者的電腦和手機(jī)插龄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來科展,“玉大人均牢,你說我怎么就攤上這事〔哦茫” “怎么了徘跪?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)琅攘。 經(jīng)常有香客問我垮庐,道長(zhǎng),這世上最難降的妖魔是什么坞琴? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任哨查,我火速辦了婚禮,結(jié)果婚禮上剧辐,老公的妹妹穿的比我還像新娘寒亥。我一直安慰自己,他們只是感情好浙于,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布护盈。 她就那樣靜靜地躺著挟纱,像睡著了一般羞酗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上紊服,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天檀轨,我揣著相機(jī)與錄音,去河邊找鬼欺嗤。 笑死参萄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的煎饼。 我是一名探鬼主播讹挎,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了筒溃?” 一聲冷哼從身側(cè)響起马篮,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怜奖,沒想到半個(gè)月后浑测,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歪玲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年迁央,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滥崩。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岖圈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钙皮,到底是詐尸還是另有隱情幅狮,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布株灸,位于F島的核電站崇摄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏慌烧。R本人自食惡果不足惜逐抑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望屹蚊。 院中可真熱鬧厕氨,春花似錦、人聲如沸汹粤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嘱兼。三九已至国葬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芹壕,已是汗流浹背汇四。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留踢涌,地道東北人通孽。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像睁壁,于是被迫代替她去往敵國(guó)和親背苦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子互捌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 掉坑 記得在笨鳥海淘做倉(cāng)庫(kù)管理系統(tǒng)的時(shí)候,我用Windows寫倉(cāng)庫(kù)管理軟件行剂。當(dāng)時(shí)系統(tǒng)用的是Windows 10疫剃。微...
    跳坑的碼農(nóng)閱讀 7,139評(píng)論 0 2
  • 整理自如下文章: iOS學(xué)習(xí)之iOS沙盒(sandbox)機(jī)制和文件操作(一) http://blog.csdn....
    Kevin_Junbaozi閱讀 866評(píng)論 0 3
  • 一、簡(jiǎn)介 1.1 概念:每個(gè)iOS應(yīng)用都有自己的應(yīng)用沙盒硼讽,應(yīng)用沙盒就是文件系統(tǒng)目錄巢价。 1.2 核心:sandbox...
    PersonChen_QJ閱讀 10,097評(píng)論 1 6
  • 前言:突然想學(xué)習(xí)一下,沙盒固阁,看了那么多博客壤躲,我四處的搜集一下總結(jié)一下,為了以后方便學(xué)習(xí)备燃,留存一篇整合的文章碉克。 一、...
    麥穗0615閱讀 12,226評(píng)論 5 28
  • 一次次在夜里沉睡 一次次在夜里蘇醒 我眼看東方升起皎白 只因心里有你 我模糊了許多夢(mèng)境與真實(shí) 我從未遇見你 可是你...
    關(guān)爾小米閱讀 363評(píng)論 0 1