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,也就是說,當管理者按到具有 “
” 圖示的功能時,例如在程式的捷徑上按滑右鍵,選取「
以系統管理員身份執行」,會出現以下選項:
.png)
當管理者點選 “繼續” 按鈕時,就會使用具管理特權的 Access Token 來進行這個動作。這個提升特權的畫面其實有三種不同的標題顏色:
![]() |
![]() |
![]() |
| 作業系統內建程式 | 已簽署的應用程式 | 未已簽署的應用程式 |
在 Windows Vista 可以在控制台中關閉 UAC 這個功能。
UAC 最大的好處是安全性,管理者再也不需要和過去一樣,一個人要記兩個帳號密碼,一個是管理者、一個是一般使用者,平常用一般使用者登入,在需要管理特權時,使用在程式捷徑上按右鍵,選取「執行為…」的方法輸入管理者帳號來取得特權。
在 Windows 7 的控制台中則可以進一步的設定提升特權時的通知畫面出現的頻率 (但是不關閉 UAC):
.png)
「控制台/使用者帳戶和家庭安全/使用者帳戶/變更使用者帳戶控制設定」
在群組原則中也可以設定:
.png)
不過由於一般使用者只有一個 Access Token,所以如果一般使用者去按到了有 “
” 符號的功能時,會出現要使用者輸入帳號密碼的畫面,使用者必須輸入具有 Administrators 權限的帳戶,才可以拿到新的 Access Token 來執行該工作。
.png)
除了在程式的捷徑上按滑右鍵,選取「
以系統管理員身份執行」的方法來提升特權之外,其實還有其它方式可以達到相同的效果。
在程式的捷徑內容畫面上,選取「進階」鈕,勾選「以系統管理員身份執行」:
.png)
在應用程式執行檔所在的資料夾,建立應用程式組態設定檔 (manifest 檔),這個檔案的名字必須是執行檔的名字加上 .config 副檔名,例如 demo.exe 執行檔的設定檔名為 demo.exe.config,將該設定檔內容設定如下:
.png)
這樣以後執行該程式時就會以提高特權的方式執行。
在應用程式專案中內嵌上述的 manifest 檔。
VB: 修改 My Project\app.manifest
C#: 內嵌 manifest 檔成 resource
C++: 內嵌 manifest 檔
使用 mt.exe 將 manifest 檔嵌入執行檔
mt -manifest demo.exe.manifest -outputresource:demo.exemt 工具程式使用參考:
http://msdn.microsoft.com/en-us/library/aa375649(v=vs.85).aspx
使用 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%
不要在程式第一次執行時進行組態設定,而是在安裝過程中做相關需要管理權限的組態設定,因為在安裝時一定具有管理特權。
不要在程式中檢查使用者是否有管理權限,因為如果使用者不以提升特權的方式執行程式,程式自己是檢查不出管理特權的。
參考資料:
- https://msdn.microsoft.com/en-us/library/bb756996.aspx
- https://msdn.microsoft.com/en-us/library/bb756973.aspx
- https://msdn.microsoft.com/en-us/library/bb756929.aspx
.png)
.png)
.png)