共用方式為


沙箱化 Xamarin.Mac 應用程式

本文涵蓋在 App Store 上發行的 Xamarin.Mac 應用程式沙箱。 它涵蓋進入沙盒化的所有元素,例如容器目錄、權利、使用者決定的許可權、許可權區隔和核心強制執行。

概觀

在 Xamarin.Mac 應用程式中使用 C# 和 .NET 時,您可以像使用 Objective-C 或 Swift 一樣,將應用程式沙盒化。

An example of the running app

在本文中,我們將討論在 Xamarin.Mac 應用程式中使用沙箱的基本概念,以及進入沙盒化的所有元素:容器目錄、權利、使用者決定的許可權、許可權區隔和核心強制執行。 強烈建議您先完成 Hello,Mac 文章,特別是 Xcode 和 Interface Builder 和 Outlets 和 Actions 簡介小節,因為它涵蓋我們將在本文中使用的重要概念和技術。

您可能也想要查看 Xamarin.Mac Internals 檔的公開 C# 類別/方法Objective-C一節,它也會說明 Register 用來將 C# 類別連線至Objective-C物件和 UI 元素的 和 Export 屬性。

關於應用程式沙盒

應用程式沙箱提供強大的防禦,以防止惡意應用程式在 Mac 上執行的惡意應用程式所造成的損害,方法是限制應用程式對系統資源的存取。

非沙盒化應用程式具有執行應用程式之使用者的完整許可權,而且可以存取或執行用戶可執行的任何動作。 如果應用程式包含安全性漏洞(或其使用的任何架構),駭客可能會利用這些弱點,並使用應用程式來控制其正在執行的 Mac。

藉由限制對每個應用程式資源的存取,沙箱化應用程式會提供防止在使用者計算機上執行之應用程式的竊取、損毀或惡意意圖的防線。

應用程式沙箱是 macOS 內建的訪問控制技術(在核心層級強制執行),可提供兩倍的策略:

  1. 應用程式沙箱可讓開發人員描述 應用程式如何 與OS互動,如此一來,它只會獲得完成作業所需的訪問許可權,而不再授與許可權。
  2. 應用程式沙箱可讓使用者透過 [開啟和儲存] 對話框順暢地授與系統的進一步存取權、拖放作業,以及其他常見的用戶互動。

準備實作應用程式沙盒

本文將詳細討論的應用程式沙盒元素如下:

  • 容器目錄
  • 權利
  • 用戶決定的許可權
  • 許可權分離
  • 核心強制執行

瞭解這些詳細數據之後,您將能夠在 Xamarin.Mac 應用程式中建立採用應用程式沙箱的計劃。

首先,您必須判斷您的應用程式是否為沙盒化的好候選專案(大部分的應用程式都是)。 接下來,您必須解析任何 API 不相容,並判斷您需要的應用程式沙箱哪些元素。 最後,瞭解如何使用許可權區隔將應用程式的防禦層級最大化。

採用應用程式沙盒時,您的應用程式所使用的一些檔案系統位置會有所不同。 特別是,您的應用程式會有容器目錄,將用於應用程式支援檔案、資料庫、快取,以及非用戶檔的任何其他檔案。 macOS 和 Xcode 都支援將這些類型的檔案從舊版位置移轉至容器。

沙箱化快速入門

在本節中,我們將建立使用 Web 檢視的簡單 Xamarin.Mac 應用程式(除非特別要求,否則需要在沙盒下限制的網路連線)作為開始使用應用程式沙箱的範例。

我們將確認應用程式實際上已沙盒化,並瞭解如何針對常見的應用程式沙盒錯誤進行疑難解答和解決。

建立 Xamarin.Mac 專案

讓我們執行下列動作來建立我們的範例專案:

  1. 啟動 Visual Studio for Mac,然後按兩下 [ 新增方案]。 連結。

  2. 從 [ 新增專案 ] 對話框中,選取 [Mac>應用程式>Cocoa 應用程式]:

    Creating a new Cocoa App

  3. 按下 [ 下一步] 按鈕,輸入 MacSandbox 項目名稱,然後按下 [ 建立] 按鈕:

    Entering the app name

  4. 在 Solution Pad,按兩下 Main.storyboard 檔案,以開啟它以在 Xcode 中編輯:

    Editing the main storyboard

  5. Web 檢視 拖曳到 [視窗],調整其大小以填滿內容區域,並將其設定為隨著視窗成長和縮小:

    Adding a web view

  6. 建立名為 webView之 Web 檢視的輸出:

    Creating a new outlet

  7. 返回 Visual Studio for Mac,然後按兩下 Solution Pad 中的ViewController.cs檔案,以開啟檔案以進行編輯。

  8. 新增下列 using 語句: using WebKit;

  9. ViewDidLoad讓 方法看起來如下:

    public override void AwakeFromNib ()
    {
        base.AwakeFromNib ();
        webView.MainFrame.LoadRequest(new NSUrlRequest(new NSUrl("http://www.apple.com")));
    }
    
  10. 儲存您的變更。

執行您的應用程式,並確定 Apple Website 會顯示在視窗中,如下所示:

Showing an example app run

簽署和布建應用程式

在啟用應用程式沙盒之前,我們必須先布建並簽署 Xamarin.Mac 應用程式。

讓我們執行下列動作:

  1. 登入 Apple 開發人員入口網站:

    Logging into the Apple Developer Portal

  2. 選取 [ 憑證]、[標識符和配置檔]:

    Selecting Certificates, Identifiers & Profiles

  3. 在 [Mac 應用程式],選取 [標識符]:

    Selecting Identifiers

  4. 為應用程式建立新的識別碼:

    Creating a new App ID

  5. 在 [布建配置檔] 底下,選取 [開發]:

    Selecting Development

  6. 建立新的設定檔,然後選取 [Mac 應用程式開發]:

    Creating a new profile

  7. 選擇我們在上面建立的應用程式識別碼:

    Selecting the App ID

  8. 選取此設定檔的開發人員:

    Adding developers

  9. 選取此設定檔的電腦:

    Selecting the allowed computers

  10. 提供設定檔名稱:

    Giving the profile a name

  11. 按兩下 [ 完成] 按鈕。

重要

在某些情況下,您可能需要直接從Apple開發人員入口網站下載新的布建配置檔,然後按兩下它進行安裝。 您可能也需要停止並重新啟動 Visual Studio for Mac,才能存取新的配置檔。

接下來,我們需要在開發計算機上載入新的應用程式識別碼和配置檔。 讓我們執行下列動作:

  1. 啟動 Xcode,然後從 Xcode 選單選取 [喜好設定]:

    Editing accounts in Xcode

  2. 點選 「 檢視詳細資料...」 按鈕:

    Clicking the View Details button

  3. 按兩下 [ 重新整理] 按鈕(左下角)。

  4. 按兩下 [ 完成] 按鈕。

接下來,我們需要在 Xamarin.Mac 項目中選取新的應用程式識別碼和布建配置檔。 讓我們執行下列動作:

  1. Solution Pad 中,按兩下 Info.plist 檔案以開啟它以進行編輯。

  2. 請確定套件組合識別元符合我們上述建立的應用程式識別碼(例如: : com.appracatappra.MacSandbox

    Editing the Bundle Identifier

  3. 接下來,按兩下 Entitlements.plist 檔案,並確定我們的 iCloud Key-Value StoreiCloud 容器都符合我們上述建立的應用程式識別碼(例如: com.appracatappra.MacSandbox

    Editing the Entitlements.plist file

  4. 儲存您的變更。

  5. Solution Pad 中,按兩下項目檔以開啟其 [選項] 進行編輯:

    Editign the solution's options

  6. 選取 [Mac 簽署],然後核取 [簽署應用程式套件組合] 和 [簽署安裝程式套件]。 在 [布建配置檔] 底 下,選取我們上面建立的配置檔

    Setting the provisioning profile

  7. 按兩下 [ 完成] 按鈕。

重要

您可能必須結束並重新啟動 Visual Studio for Mac,才能辨識 Xcode 所安裝的新應用程式識別碼和布建配置檔。

針對布建問題進行疑難解答

此時,您應該嘗試執行應用程式,並確定所有專案都已正確簽署並布建。 如果應用程式仍然像以前一樣執行,則一切都不錯。 發生失敗時,您可能會收到如下對話框:

An example provisioning issue dialog

以下是布建和簽署問題最常見的原因:

  • 應用程式套件組合識別碼不符合所選設定檔的應用程式識別碼。
  • 開發人員標識碼不符合所選配置檔的開發人員標識碼。
  • 所測試 Mac 的 UUID 不會註冊為所選配置檔的一部分。

如果發生問題,請在Apple Developer Portal 上修正問題、在 Xcode 中重新整理配置檔,並在 Visual Studio for Mac 中執行全新組建。

啟用應用程式沙箱

您可以選擇項目選項中的複選框來啟用應用程式沙箱。 執行下列操作:

  1. 在 Solution Pad,按兩下 Entitlements.plist 檔案以開啟它以進行編輯。

  2. 檢查 [ 啟用權利 ] 和 [啟用應用程式沙箱]

    Editing entitlements and enabling sandboxing

  3. 儲存您的變更。

此時,您已啟用應用程式沙箱,但尚未提供 Web 檢視所需的網路存取權。 如果您現在執行應用程式,您應該會取得空白視窗:

Showing the web access being blocked

確認應用程式已沙盒化

除了資源封鎖行為之外,還有三個主要方式可判斷 Xamarin.Mac 應用程式是否已成功沙盒化:

  1. 在 Finder 中,檢查資料夾的內容 ~/Library/Containers/ - 如果應用程式已沙箱化,將會有一個名為的資料夾,例如您應用程式的套件組合識別碼 (例如: ): com.appracatappra.MacSandbox

    Opening the app's bundle

  2. 系統會在活動監視器中將應用程式視為沙盒化:

    • 啟動活動監視器 (在 下 /Applications/Utilities)。
    • 選擇 [ 檢視>數據行 ],並確定 已核取 [沙盒 ] 功能表項。
    • 確定沙箱資料行會針對您的應用程式讀取 Yes

    Checking the app in the Activity Monitor

  3. 檢查應用程式二進位檔是否已沙箱化:

    • 啟動終端機應用程式。
    • 瀏覽至應用程式 bin 目錄。
    • 發出此指令: codesign -dvvv --entitlements :- executable_path (其中 executable_path 是應用程式的路徑):

    Checking the app on the command line

對沙箱化應用程式進行偵錯

調試程式會透過 TCP 連線到 Xamarin.Mac 應用程式,這表示當您啟用沙箱化時,它無法連線到應用程式,因此如果您嘗試執行未啟用適當許可權的應用程式,您會收到「無法連線到調試程式」錯誤

Setting the required options

允許傳出網路 連線(客戶端)許可權是調試程式所需的許可權,啟用此許可權將允許正常偵錯。 由於您無法在沒有偵錯的情況下進行偵錯,因此我們已更新 CompileEntitlements 的目標 msbuild ,以自動將該許可權新增至任何沙盒化以進行偵錯組建的應用程式的權利。 發行組建應該使用權利檔案中指定的權利,未經修改。

解決應用程式沙盒違規

如果沙箱化 Xamarin.Mac 應用程式嘗試存取未明確允許的資源,就會發生應用程式沙盒違規。 例如,我們的 Web 檢視無法再顯示 Apple 網站。

當 Visual Studio for Mac 中指定的權利設定不符合應用程式需求時,就會發生最常見的應用程式沙箱違規來源。 同樣地,回到我們的範例中,遺漏的網路 連線 權利,讓 Web 檢視無法運作。

探索應用程式沙盒違規

如果您懷疑 Xamarin.Mac 應用程式中發生應用程式沙箱違規,則探索問題最快的方式是使用 主控台 應用程式。

執行下列操作:

  1. 編譯有問題的應用程式,並從 Visual Studio for Mac 執行。

  2. 開啟主控台應用程式(來自 /Applications/Utilties/)。

  3. 選取 提要欄位中的所有訊息 ,然後在搜尋中輸入 sandbox

    An example of a sandboxing issue in the console

針對上述範例應用程式,您可以看到 Kernal 因為應用程式沙箱而封鎖 network-outbound 流量,因為我們尚未要求該許可權。

使用權利修正應用程式沙盒違規

既然我們已經瞭解如何尋找應用程式沙盒違規,讓我們看看如何藉由調整應用程式的權利來解決它們。

執行下列操作:

  1. 在 Solution Pad,按兩下 Entitlements.plist 檔案以開啟它以進行編輯。

  2. 在 [權利] 區段底下,核取 [允許傳出網络 連線 (用戶端) 複選框:

    Editing the entitlements

  3. 將變更儲存至應用程式。

如果我們針對範例應用程式執行上述動作,請建置並執行它,Web 內容現在會顯示如預期般顯示。

應用程式沙箱深入

應用程式沙箱所提供的訪問控制機制很少且易於瞭解。 不過,每個應用程式都會採用應用程式沙盒的方式是唯一的,且會根據應用程式的需求。

為了保護您的 Xamarin.Mac 應用程式不受惡意代碼入侵,應用程式(或其中一個連結庫或所取用的架構)中只需要單一弱點,即可控制應用程式與系統的互動。

應用程式沙箱的設計目的是要防止接管(或限制它可能造成的損害),方法是讓您指定應用程式與系統的預定互動。 系統只會授與應用程式完成其工作所需的資源存取權,而且不會再授與任何許可權。

設計應用程式沙盒時,您要針對最壞的情況進行設計。 如果應用程式遭到惡意代碼入侵,則只能存取應用程式沙箱中的檔案和資源。

權利和系統資源存取

如上所述,尚未沙盒化 Xamarin.Mac 應用程式的授與執行應用程式之使用者的完整許可權和存取權。 如果遭到惡意代碼入侵,非受保護的應用程式可以做為惡意行為的代理程式,並有可能造成傷害。

藉由啟用應用程式沙盒,您可以移除一組最少的許可權,然後使用 Xamarin.Mac 應用程式的權利,以僅需要重新啟用。

您可以編輯應用程式的 Entitlements.plist 檔案,然後從編輯器下拉式方塊中檢查或選取所需的許可權,以修改應用程式的應用程式沙箱資源:

Editing the entitlements

容器目錄和檔案系統存取

當您的 Xamarin.Mac 應用程式採用應用程式沙箱時,它可以存取下列位置:

  • 應用程式容器目錄 - 第一次執行時,OS 會建立一個特殊的 Container Directory ,其中所有資源都可供其存取。 應用程式將具有此目錄的完整讀取/寫入存取權。
  • 應用程式群組容器目錄 - 您的應用程式可以授與一或多個 群組容器的存取權,這些容器 在相同群組中的應用程式之間共用。
  • 使用者指定的檔案 - 您的應用程式會自動取得使用者明確開啟或拖放到應用程式之檔案的存取權。
  • 相關專案 - 使用適當的權利,您的應用程式可以存取具有相同名稱但擴展名不同的檔案。 例如,已儲存為 .txt 檔案和 .pdf的檔。
  • 暫存目錄、命令行工具目錄,以及特定的世界可讀取位置 - 您的應用程式具有不同程度地存取系統所指定之其他定義位置中的檔案。

應用程式容器目錄

Xamarin.Mac 應用程式的應用程式容器目錄具有下列特性:

  • 它位於使用者主目錄的隱藏位置(通常是 ~Library/Containers),而且可以使用應用程式內的函式來存取 NSHomeDirectory 。。 因為它是在主目錄中,每個用戶都會取得自己的應用程式容器。
  • 應用程式具有容器目錄及其所有子目錄和檔案的無限制讀取/寫入存取權。
  • 大部分的 macOS 尋找路徑 API 都與應用程式的容器相對。 例如,容器將有自己的 連結庫 (透過 NSLibraryDirectory存取)、 應用程式支援喜好設定 子目錄。
  • macOS 會透過程式代碼簽署,建立並強制執行與應用程式與其容器之間的連線。 即使是另一個應用程式嘗試使用其 套件組合標識符詐騙應用程式,它也無法存取容器,因為程式代碼簽署。
  • 容器不適用於用戶產生的檔案。 而是針對應用程式使用的檔案,例如資料庫、快取或其他特定類型的數據。
  • 對於 鞋盒 類型的應用程式(例如 Apple 的相片應用程式),使用者的內容會進入容器。

重要

不幸的是,Xamarin.Mac 還沒有 100% 的 API 涵蓋範圍(與 Xamarin.iOS 不同),因此 NSHomeDirectory API 尚未對應到目前的 Xamarin.Mac 版本。

作為暫時的因應措施,您可以使用下列程序代碼:

[System.Runtime.InteropServices.DllImport("/System/Library/Frameworks/Foundation.framework/Foundation")]
public static extern IntPtr NSHomeDirectory();

public static string ContainerDirectory {
    get {
        return ((NSString)ObjCRuntime.Runtime.GetNSObject(NSHomeDirectory())).ToString ();
        }
}

應用程式群組容器目錄

從 Mac macOS 10.7.5 開始,應用程式可以使用 com.apple.security.application-groups 權利來存取群組中所有應用程式通用的共用容器。 您可以將此共用容器用於非使用者面向內容,例如資料庫或其他類型的支援檔案(例如快取)。

群組容器會自動新增至每個應用程式的沙盒容器(如果他們是群組的一部分),並儲存在 ~/Library/Group Containers/<application-group-id>。 群組識別碼 必須 以您的開發小組標識碼和句號開頭,例如:

<team-id>.com.company.<group-name>

如需詳細資訊,請參閱Apple在權利金鑰參考將應用程式新增至應用程式群組。

應用程式容器外部的Powerbox和檔案系統存取

沙箱化 Xamarin.Mac 應用程式可以透過下列方式存取其容器外部的檔案系統位置:

  • 在使用者的特定方向上(透過開啟和儲存對話框或其他方法,例如拖放)。
  • 使用特定檔案系統位置的權利(例如 /bin/usr/lib)。
  • 當檔案系統位置位於世界可讀取的特定目錄中時(例如共用)。

Powerbox 是 macOS 安全性技術,可與用戶互動,以擴充沙盒化 Xamarin.Mac 應用程式的檔案存取許可權。 Powerbox 沒有 API,但在應用程式呼叫 NSOpenPanelNSSavePanel時會以透明方式啟用。 Powerbox 存取是透過您為 Xamarin.Mac 應用程式設定的權利來啟用。

當沙箱化應用程式顯示 [開啟] 或 [儲存] 對話框時,Powerbox 會顯示視窗(而非 AppKit),因此可以存取使用者可存取的任何檔案或目錄。

當使用者從 [開啟] 或 [儲存] 對話框選取檔案或目錄時,Powerbox 會將相關聯的路徑新增至應用程式的沙箱。

此外,系統會自動將下列專案允許沙盒化應用程式:

  • 連線 系統輸入法。
  • [服務] 功能選取的使用者呼叫服務 (僅適用於服務提供商標示為 沙盒應用程式 安全的服務)。
  • 開啟使用者從 [開啟最近使用] 功能表選擇的檔案。
  • 在其他應用程式之間使用複製與貼上。
  • 從下列世界可讀取位置讀取檔案:
    • /bin
    • /sbin
    • /usr/bin
    • /usr/lib
    • /usr/sbin
    • /usr/share
    • /System
  • 讀取和寫入 所建立目錄中的 NSTemporaryDirectory檔案。

根據預設,沙盒化 Xamarin.Mac 應用程式開啟或儲存的檔案會保持可存取性,直到應用程式終止為止(除非應用程式結束時仍開啟檔案)。 開啟的檔案會在下次啟動應用程式時,透過macOS繼續功能自動還原至應用程式的沙箱。

若要為位於 Xamarin.Mac 應用程式容器外部的檔案提供持續性,請使用安全性範圍書籤(請參閱下方)。

應用程式沙箱可讓應用程式存取具有相同檔名但擴展名不同的相關專案。 此功能有兩個部分:a) 應用程式 Info.plst 檔案中相關延伸模組的清單,b) 程式代碼會告訴沙盒應用程式會使用這些檔案執行什麼動作。

有兩種情況很合理:

  1. 應用程式必須能夠儲存不同版本的檔案(具有新的擴展名)。 例如,將 .txt 檔案導出至 .pdf 檔案。 若要處理這種情況,您必須使用 NSFileCoordinator 來存取檔案。 您會先呼叫 WillMove(fromURL, toURL) 方法,將檔案移至新的擴展名,然後呼叫 ItemMoved(fromURL, toURL)
  2. 應用程式必須開啟具有一個擴展名的主要檔案,以及具有不同擴展名的數個支持檔案。 例如,電影和子標題檔案。 NSFilePresenter使用取得次要檔案的存取權。 將主要檔案提供給 PrimaryPresentedItemURL 屬性,並將次要檔案提供給 PresentedItemURL 屬性。 開啟主要檔案時,呼叫 AddFilePresenter 類別的 NSFileCoordinator 方法以註冊次要檔案。

在這兩種情況下,應用程式的 Info.plist 檔案必須宣告應用程式可以開啟的檔案類型。 針對任何檔案類型,將 (值為YES) 新增NSIsRelatedItemType至陣列中的CFBundleDocumentTypes專案。

使用沙箱化應用程式開啟和儲存對話框行為

從沙箱化 Xamarin.Mac 應用程式呼叫這些限制時,會NSSavePanel對其NSOpenPanel設定下列限制:

  • 您無法以程式設計方式叫用 [ 確定] 按鈕。
  • 您無法在 中 NSOpenSavePanelDelegate以程式設計方式改變使用者的選取範圍。

此外,下列繼承修改已就緒:

  • 非沙盒化應用程式 - NSOpenPanelNSSavePanel``NSPanel``NSWindow``NSResponder``NSObject``NSOpenPanel``NSSavePanel``NSObject``NSOpenPanel``NSSavePanel

安全性範圍的書籤和持續性資源存取

如上所述,沙盒化 Xamarin.Mac 應用程式可以透過直接用戶互動來存取其容器外部的檔案或資源(如 PowerBox 提供)。 不過,存取這些資源不會在應用程式啟動或系統重新啟動之間自動保存。

藉由使用 安全性範圍書籤,沙盒化 Xamarin.Mac 應用程式可以保留使用者意圖,並在應用程式重新啟動後維護對指定資源的存取權。

安全性範圍的書籤類型

使用安全性範圍書籤和永續性資源存取時,有兩個 Sistine 使用案例:

  • 應用程式範圍書籤提供使用者指定檔案或資料夾的持續性存取權。

    例如,如果沙盒化 Xamarin.Mac 應用程式允許用來開啟外部文件進行編輯(使用 NSOpenPanel),應用程式就可以建立應用程式範圍書籤,以便日後再次存取相同的檔案。

  • 檔範圍書籤提供子檔案的特定文件持續性存取權。

例如,建立項目檔的影片編輯應用程式,可存取個別影像、視訊剪輯和音效檔案,稍後再合併成單一電影。

當使用者將資源文件匯入專案時(透過 , NSOpenPanel應用程式會為儲存在專案中的專案建立檔範圍書籤,讓應用程式一律可以存取該檔案。

任何可以開啟書籤數據和檔本身的應用程式都可以解析檔範圍書籤。 這支援可移植性,可讓使用者將專案檔傳送給其他使用者,並讓所有書籤也可供他們使用。

重要

檔範圍書籤只能指向單一檔案,而不能指向資料夾,而且該檔案不能位於系統所使用的位置(例如 /private/Library)。

使用安全性範圍的書籤

使用任一類型的安全性範圍書籤,需要您執行下列步驟:

  1. 在需要使用安全性範圍書籤 的 Xamarin.Mac 應用程式中設定適當的權利 - 針對應用程式範圍書籤,請將 com.apple.security.files.bookmarks.app-scope 權利密鑰設定為 true。 針對 [檔案範圍書籤],將 com.apple.security.files.bookmarks.document-scope [權利] 索引鍵設定為 true
  2. 建立安全性範圍書籤 - 您將針對使用者提供存取權的任何檔案或資料夾執行此動作(例如,透過 NSOpenPanel ),應用程式將需要持續存取權。 public virtual NSData CreateBookmarkData (NSUrlBookmarkCreationOptions options, string[] resourceValues, NSUrl relativeUrl, out NSError error)使用類別的 NSUrl 方法來建立書籤。
  3. 解決安全性範圍書籤 - 當應用程式需要再次存取資源時(例如,重新啟動后)需要將書籤解析為安全性範圍的 URL。 public static NSUrl FromBookmarkData (NSData data, NSUrlBookmarkResolutionOptions options, NSUrl relativeToUrl, out bool isStale, out NSError error)使用類別的 NSUrl 方法來解析書籤。
  4. 明確通知系統您想要從安全性範圍 URL 存取檔案 - 在取得上述安全性範圍 URL 之後,或稍後想要在放棄存取資源之後重新取得資源的存取權時,必須立即完成此步驟。 StartAccessingSecurityScopedResource ()呼叫 類別的 NSUrl 方法,開始存取安全性範圍 URL。
  5. 明確通知系統,您已完成從安全性範圍 URL 存取檔案 - 儘快,當應用程式不再需要檔案的存取權時,您應該通知系統 (例如,如果使用者關閉它)。 StopAccessingSecurityScopedResource ()呼叫 類別的 NSUrl 方法,以停止存取安全性範圍 URL。

放棄資源的存取權之後,您必須再次返回步驟 4 以重新建立存取權。 如果重新啟動 Xamarin.Mac 應用程式,您必須返回步驟 3 並重新解析書籤。

重要

無法釋放安全性範圍 URL 資源的存取權,會導致 Xamarin.Mac 應用程式流失核心資源。 因此,應用程式將無法再將檔案系統位置新增至其容器,直到重新啟動為止。

應用程式沙箱和程式代碼簽署

啟用應用程式沙箱並啟用 Xamarin.Mac 應用程式的特定需求之後(透過權利),您必須撰寫程式代碼簽署專案,沙箱才會生效。 您必須執行程式代碼簽署,因為應用程式沙箱所需的權利會連結到應用程式的簽章。

macOS 會強制應用程式容器與其程式代碼簽章之間的連結,如此一來,即使它詐騙應用程式套件組合標識碼,其他應用程式也無法存取該容器。 此機制的運作方式如下:

  1. 當系統建立應用程式的容器時,它會在該容器上設定 存取控制 清單 (ACL)。 清單中的初始訪問控制專案包含應用程式的 指定需求 (DR),其描述如何辨識應用程式的未來版本(升級時)。
  2. 每次具有相同套件組合識別碼的應用程式啟動時,系統會檢查應用程式的程式代碼簽章是否符合容器 ACL 中其中一個專案中指定的指定需求。 如果系統找不到相符專案,它會防止應用程式啟動。

程式代碼簽署的運作方式如下:

  1. 建立 Xamarin.Mac 專案之前,請先從 Apple 開發人員入口網站取得開發憑證、散發憑證和開發人員標識符憑證。
  2. 當 Mac App Store 散發 Xamarin.Mac 應用程式時,會使用 Apple 程式代碼簽章進行簽署。

測試和偵錯時,您將使用您簽署的 Xamarin.Mac 應用程式版本(將用來建立應用程式容器)。 稍後,如果您想要從Apple App Store測試或安裝版本,則會使用Apple簽章進行簽署,且無法啟動(因為它沒有與原始應用程式容器相同的程式代碼簽章)。 在此情況下,您將會收到類似下列的當機報告:

Exception Type:  EXC_BAD_INSTRUCTION (SIGILL)

若要修正此問題,您必須調整 ACL 進入,以指向 Apple 簽署的應用程式版本。

如需建立和下載沙箱所需的布建配置檔的詳細資訊,請參閱 上面的簽署和布建應用程式 一節。

調整 ACL 專案

若要允許 Apple 簽署版本的 Xamarin.Mac 應用程式執行,請執行下列動作:

  1. 開啟終端機應用程式 (在 中 /Applications/Utilities)。
  2. 開啟 Xamarin.Mac 應用程式 Apple 簽署版本的 Finder 視窗。
  3. 在[終端機] 視窗中輸入 asctl container acl add -file
  4. 從 [尋找工具] 視窗拖曳 Xamarin.Mac 應用程式的圖示,並將其放在 [終端機] 視窗上。
  5. 檔案的完整路徑將會新增至終端機中的 命令。
  6. Enter 以執行命令。

容器的 ACL 現在包含 Xamarin.Mac 應用程式和 macOS 兩個版本的指定程式代碼需求,現在允許任一版本執行。

顯示 ACL 程式代碼需求清單

您可以執行下列動作來檢視容器 ACL 中的程式碼需求清單:

  1. 開啟終端機應用程式 (在 中 /Applications/Utilities)。
  2. 輸入 asctl container acl list -bundle <container-name>
  3. Enter 以執行命令。

<container-name>通常是 Xamarin.Mac 應用程式的套件組合識別碼。

設計應用程式沙箱的 Xamarin.Mac 應用程式

設計應用程式沙箱的 Xamarin.Mac 應用程式時,應該遵循一般工作流程。 也就是說,在應用程式中實作沙盒化的具體細節,對指定的應用程式功能而言將是獨一無二的。

採用應用程式沙箱的六個步驟

設計應用程式沙箱的 Xamarin.Mac 應用程式通常包含下列步驟:

  1. 判斷應用程式是否適合沙盒化。
  2. 設計開發和散發策略。
  3. 解決任何 API 不相容的問題。
  4. 將必要的應用程式沙盒權利套用至 Xamarin.Mac 專案。
  5. 使用 XPC 新增許可權區隔。
  6. 實作移轉策略。

重要

您不僅必須將應用程式套件組合中的主要可執行檔沙箱化,而且每個隨附的協助程式應用程式或該套件組合中的工具。 這是從 Mac App Store 散發的任何應用程式的必要專案,如果可能的話,應該針對任何其他形式的應用程式散發來完成。

如需 Xamarin.Mac 應用程式套件組合中所有可執行二進位檔的清單,請在終端機中輸入下列命令:

find -H [Your-App-Bundle].app -print0 | xargs -0 file | grep "Mach-O .*executable"

其中 [Your-App-Bundle] 是應用程式套件組合的名稱和路徑。

判斷 Xamarin.Mac 應用程式是否適合沙盒化

大部分的 Xamarin.Mac 應用程式與應用程式沙箱完全相容,因此適合沙箱化。 如果應用程式需要應用程式沙箱不允許的行為,您應該考慮替代方法。

如果您的應用程式需要下列其中一種行為,它與應用程式沙箱不相容:

  • 授權服務 - 使用應用程式沙箱時,您無法使用授權服務 C 參考中所述的函式。
  • 輔助功能 API - 您無法將輔助應用程式沙箱化,例如螢幕助讀程式或控制其他應用程式的應用程式。
  • 將 Apple 事件傳送至任意應用程式 - 如果應用程式需要將 Apple 事件傳送至未知的任意應用程式,就無法進行沙盒化。 如需已知的已呼叫應用程式清單,應用程式仍然可以沙盒化,而權利必須包含呼叫的應用程式清單。
  • 將分散式通知中的使用者資訊字典傳送至其他工作 - 使用應用程式沙盒時,您無法在張貼至NSDistributedNotificationCenter物件以傳訊其他工作時包含userInfo字典。
  • 載入核心延伸模組 - 應用程式沙箱禁止載入核心延伸模組。
  • 應用程式沙箱禁止在 [開啟和儲存] 對話框中 模擬使用者輸入 - 以程序設計方式操作 [開啟] 或 [儲存] 對話框以模擬或改變使用者輸入。
  • 存取或設定其他應用程式的 喜好設定 - 應用程式沙箱禁止管理其他應用程式的設定。
  • 設定網路 設定 - 應用程式沙箱禁止操作網路 設定。
  • 終止其他應用程式 - 應用程式沙箱禁止使用 NSRunningApplication 終止其他應用程式。

解析 API 不相容

設計應用程式沙箱的 Xamarin.Mac 應用程式時,您可能會遇到某些 macOS API 的使用不相容。

以下是一些常見問題,以及您可以加以解決的事項:

  • 開啟、儲存和追蹤檔 - 如果您使用 以外的 NSDocument任何技術來管理檔,您應該因為應用程式沙箱的內建支援而切換到它。 NSDocument 當使用者在 Finder 中移動檔時,會自動與 PowerBox 搭配運作,並提供在沙箱中保留文件的支援。
  • 保留文件系統資源的 存取權 - 如果 Xamarin.Mac 應用程式相依於其容器外部資源的持續性存取權,請使用安全性範圍的書籤來維護存取權。
  • 建立應用程式的登入專案 - 使用應用程式 沙箱時,您無法使用 LSSharedFileList 建立登入專案,也無法使用 LSRegisterURL來操作啟動服務的狀態。 SMLoginItemSetEnabled使用如 Apples 使用服務管理架構檔新增登入專案中所述的函式。
  • 存取使用者資料 - 如果您使用 POSIX 函式,例如 getpwuid 從目錄服務取得使用者的主目錄,請考慮使用 Cocoa 或 Core Foundation 符號,例如 NSHomeDirectory
  • 存取其他應用程式的 喜好設定 - 因為應用程式沙箱會將尋找路徑 API 導向至應用程式的容器,因此修改喜好設定會在該容器內進行,並存取不允許的其他應用程式喜好設定。
  • 在 Web 檢視 中使用 HTML5 內嵌視訊 - 如果 Xamarin.Mac 應用程式使用 WebKit 播放內嵌 HTML5 影片,您也必須連結應用程式與 AV Foundation 架構。 應用程式沙箱會防止 CoreMedia 播放這些影片,否則為 。

套用必要的應用程式沙盒權利

您必須編輯您想要在應用程式沙箱中執行之任何 Xamarin.Mac 應用程式的權利,並核取 [ 啟用應用程式沙盒] 複選框。

根據應用程式的功能,您可能需要讓其他權利存取OS功能或資源。 當您將要求的權利降到執行應用程式所需的最低權利降到最低時,應用程式沙盒效果最佳,因此只要隨機啟用權利即可。

若要判斷 Xamarin.Mac 應用程式需要哪些權利,請執行下列動作:

  1. 啟用應用程式沙箱並執行 Xamarin.Mac 應用程式。
  2. 執行應用程式的功能。
  3. 開啟主控台應用程式 (可在 中/Applications/Utilities取得),並在 [所有訊息] 記錄檔中尋找sandboxd違規。
  4. 針對每個 sandboxd 違規,請使用應用程式容器而非其他檔案系統位置來解決問題,或套用應用程式沙箱權利來啟用對受限制操作系統功能的存取。
  5. 重新執行並再次測試所有 Xamarin.Mac 應用程式功能。
  6. 重複,直到解決所有 sandboxd 違規為止。

使用 XPC 新增許可權分隔

針對應用程式沙盒開發 Xamarin.Mac 應用程式時,請查看應用程式在許可權和存取方面的行為,然後考慮將高風險作業分成自己的 XPC 服務。

如需詳細資訊,請參閱Apple建立 XPC 服務和精靈和服務程序設計指南

實作移轉策略

如果您要發行先前未沙盒化的新 Xamarin.Mac 應用程式沙盒化版本,您必須確保目前的使用者具有順暢的升級路徑。

如需如何實作容器移轉指令清單的詳細資訊,請參閱Apple將 應用程式移轉至沙盒 檔。

摘要

本文已詳細探討 Xamarin.Mac 應用程式的沙盒化。 首先,我們建立了簡單的 Xamarin.Mac 應用程式,以顯示應用程式沙箱的基本概念。 接下來,我們示範如何解決沙盒違規問題。 然後,我們深入探討應用程式沙箱,最後,我們探討了為應用程式沙盒設計 Xamarin.Mac 應用程式。