使用者帳戶控制 (User Account Control, UAC)


UAC 其實是從 Windows XP 到 Windows Vista / 7,影響應用程式最為重大的一個改變,絕大部份應用程式不相容都是因為這個功能所造成。不過在談到 UAC 之前得先說明一下 Access Token 這個東西: 當使用者登入系統時,作業系統中的本機安全子系統 (Local Security Sub System, LSA) 會為該使用者產生一個 Access Token (儲存在記憶體中),在 Access Token 內包含了以下三個內容:

  • 使用者的 SID
  • 使用者所屬的群組的 SID (可能有多個群組)
  • 使用者的特權 (例如: 關機、修改系統時間、…)

當使用者在存取任何資源 (檔案、印表機、…) 時,本機安全子系統就會檢查該資源的存取控制清單 (Access Control List, ACL),看看 ACL 中是否有出現 Access Token 中的 SID (使用者或群組),以便於計算出使用者對於該資源所擁有的權限。

在 Windows XP、Windows Server 2003 中,不論是一般使用者或是系統管理者登入 Windows 都會有這麼一個 Access Token,但是從 Windows Vista 開始,系統管理者 ( 屬於 Administrators 群組 ) 在登入 Windows 時,本機安全子系統會產生兩個 Access Token 給管理者,一個是原本具管理特權的 Access Token,另一個是一般使用者特權的 Access Token。

  • 具管理特權的 Access Token

    • 使用者的 SID
    • 群組的 SID ( 包含了 Administrators )
    • 所有的特權 ( 包含了關機、修改系統時間、… )
  • 一般使用者特權的 Access Token

    • 使用者的 SID
    • 群組的 SID (包含 Administrators)
    • 使用者特權 (包含任何管理特權,例如:關機、修改系統時間、…)

當管理在進行任何動作時,都是以一般使用者特權的 Access Token 身份來進行,當需要管理特權時才會使用到具管理特權的 Access Token,也就是說,當管理者按到具有 “” 圖示的功能時,例如在程式的捷徑上按滑右鍵,選取「以系統管理員身份執行」,會出現以下選項:

當管理者點選 “繼續” 按鈕時,就會使用具管理特權的 Access Token 來進行這個動作。這個提升特權的畫面其實有三種不同的標題顏色:

作業系統內建程式 已簽署的應用程式 未已簽署的應用程式

在 Windows Vista 可以在控制台中關閉 UAC 這個功能。

UAC 最大的好處是安全性,管理者再也不需要和過去一樣,一個人要記兩個帳號密碼,一個是管理者、一個是一般使用者,平常用一般使用者登入,在需要管理特權時,使用在程式捷徑上按右鍵,選取「執行為…」的方法輸入管理者帳號來取得特權。

在 Windows 7 的控制台中則可以進一步的設定提升特權時的通知畫面出現的頻率 (但是不關閉 UAC):


「控制台/使用者帳戶和家庭安全/使用者帳戶/變更使用者帳戶控制設定」

在群組原則中也可以設定:

不過由於一般使用者只有一個 Access Token,所以如果一般使用者去按到了有 “” 符號的功能時,會出現要使用者輸入帳號密碼的畫面,使用者必須輸入具有 Administrators 權限的帳戶,才可以拿到新的 Access Token 來執行該工作。

除了在程式的捷徑上按滑右鍵,選取「以系統管理員身份執行」的方法來提升特權之外,其實還有其它方式可以達到相同的效果。

  • 在程式的捷徑內容畫面上,選取「進階」鈕,勾選「以系統管理員身份執行」:

     

     

  • 在應用程式執行檔所在的資料夾,建立應用程式組態設定檔 (manifest 檔),這個檔案的名字必須是執行檔的名字加上 .config 副檔名,例如 demo.exe 執行檔的設定檔名為 demo.exe.config,將該設定檔內容設定如下:

    這樣以後執行該程式時就會以提高特權的方式執行。

  • 在應用程式專案中內嵌上述的 manifest 檔。

  • 使用 Application Compatibility Toolkit (ACT) 來套用 UAC 修正。
    下載: http://go.microsoft.com/fwlink/?LinkID=82101

  • 分離管理程式碼

    由於正在執行的處理程序是不能提升權限的,因此在程式設計上不要假設使用者都是管理身份,而是將需要管理特權的程式碼與主程式分離,有以下三種解決方式:

    • Service Broker Model

      使用具有管理特權的帳戶來執行 Windows 服務,將所有需要提升特權才能執行的動作放在這個 Windows 服務中,應用程式再使用 RPC 與 Windows 服務通訊,以進行管理工作。

    • Side by Side Processes

      建立另一個具有管理特權的處理程序,應用程式主處理程序再使用以下兩種方式與它溝通:

      • Shared memory
      • RPC
      • 建立一個管理用的 COM 物件來做需要提升權限的工作,再使用 CoCreateAsAdmin 這個 API 函式來建立具有管理特權的 COM 元件處理程序。
  • 給程式設計師的建議

    • 在程式第一次執行時,進行個別使用者的組態設定將組態設定檔放置到:

      • 本機:%LOCALAPPDATA%
      • 漫遊:%APPDATA%
      • 共用:%ALLUSERPROFILE%
    • 不要在程式第一次執行時進行組態設定,而是在安裝過程中做相關需要管理權限的組態設定,因為在安裝時一定具有管理特權。

    • 不要在程式中檢查使用者是否有管理權限,因為如果使用者不以提升特權的方式執行程式,程式自己是檢查不出管理特權的。

參考資料:

 

返回上一頁 >