每當建立檔案時,除了一些基本檔案屬性(建立時間,修改時間……),系統還會將建立檔案的使用者名稱稱和組名稱儲存起來。這些安全資訊也就是所謂的“安全描述項”(Security Descriptor)。安全描述項中不僅可以包含建立者的使用者資訊。還可以儲存該檔案的針對使用者認證的特殊要求,就是描述指定使用者對該檔案的許可權。比如,使用者A可以對該檔案進行任何操作。而使用者B只能讀(訪問)不能修改。而使用者C則無法對該檔案進行任何操作(檔案對他來說是不可見的)。安全描述項還可以包含系統存取控制清單,可以設定某些許可權操作後將相關資訊反饋到系統安全事件薄中。
好了,那麼如果用常規方法建立檔案的話,檔案的安全資訊中的存取控制是預設的,這個預設是指:可以是空的,也可以是繼承目錄的存取控制(如果目錄設定了相應存取控制和繼承選項的話)。比如,一個最簡單的例子,我在我的案頭上建立一個檔案,這個檔案很顯然我能隨意操作它,其他管理員也可以,但受限使用者不能訪問。這是由於案頭(Desktop檔案夾)位於使用者賬戶檔案夾中並繼承了相關使用者目錄的檔案系統存取控制設定(使用者檔案夾:Windows Vista+在Users檔案夾內,Windows XP在Documents and Settings檔案夾內)。
(在檔案的屬性菜單的“安全”選項卡中可以瀏覽或者修改具體安全設定,當然不是所有使用者都有許可權進行訪問或者修改這些設定的)
可以看到,我的賬戶(Mgen)是擁有對該檔案的全部控制的(Full Control的Allow有對號),同時上面的“組或者使用者名稱稱中”沒有Users組或者Guest使用者,說明他們根本無法訪問的。
如果在D盤隨便找一個檔案,顯然受限制使用者預設是可以訪問的,上面就會出現Users使用者組,但是受限使用者只能訪問或者執行,不能修改。
.NET中的System.Security.AccessControl命名空間內提供了對Windows系統的存取控制的操作。如果你對Windows存取控制比較熟悉但不瞭解.NET中的封裝API,可以參考我的另外一篇文章:淺談Windows存取控制在.NET(C#)中的實現(ACE, SD, DACL, SACL)。
安全描述項缺少不了建立該安全性實體的,這個通過WindowsIdentity.GetCurrent得到(返回一個繼承IIdentity的WindowsIdentity對象),GetCurrent代表返回當前Windows使用者的標識。
接著針對檔案系統對象的安全描述項是System.Security.AccessControl.FileSystemSecurity,由於操作檔案,我們使用它的衍生類別FileSecurity類。最後把存取控制對象加入到存取控制清單中,利用FileStream的建構函式創造出這樣一個具有顯式存取控制定義的檔案。
代碼:
try
{
//using System.Security.Principal;
//using System.Security.AccessControl;
//using System.IO;
//擷取目前使用者的WindowsIdentity
var currentIdentity = WindowsIdentity.GetCurrent();
//建立訪問規則(僅為目前使用者添加全部控制)
var accessRule = new FileSystemAccessRule(currentIdentity.User, FileSystemRights.FullControl, AccessControlType.Allow);
//建立安全描述項:針對檔案的FileSecurity對象
var fileSecur = new FileSecurity();
//將訪問規則添加
fileSecur.AddAccessRule(accessRule);
//用FileStream的建構函式建立具有顯式訪問規則的檔案
var file = new FileStream("text.txt", FileMode.Create, FileSystemRights.Write, FileShare.None, 1024, FileOptions.None, fileSecur);
var bytes = Encoding.ASCII.GetBytes("hello");
file.Write(bytes, 0, bytes.Length);
file.Close();
Console.WriteLine("建立成功");
}
catch (Exception ex)
{
Console.WriteLine("錯誤:{0}", ex.Message);
}
開啟這個檔案的屬性,可以看到,只有目前使用者才可以操作該檔案: