.NET 控制Windows文件和目錄訪問權限研究(FileSystemAccessRule)

前一段時間學習了.net 控制windows文件和目錄權限的相關內容,期間作了一些總結。想把這方面的研究跟你們分享,一塊兒學習。其中難免得有些用詞不太標準的地方,但願你們留言指正,我加以修改。html

首先,咱們利用一個方法做爲示例:windows

        /// <summary>
        /// 爲指定用戶組,受權目錄指定徹底訪問權限
        /// </summary>
        /// <param name="user">用戶組,如Users</param>
        /// <param name="folder">實際的目錄</param>
        /// <returns></returns>
        private static bool SetAccess(string user, string folder)
        {
            //定義爲徹底控制的權限
            const FileSystemRights Rights = FileSystemRights.FullControl;

            //添加訪問規則到實際目錄
            var AccessRule = new FileSystemAccessRule(user, Rights,InheritanceFlags.None,PropagationFlags.NoPropagateInherit, AccessControlType.Allow);
            var Info = new DirectoryInfo(folder);
            var Security = Info.GetAccessControl(AccessControlSections.Access);
            bool Result;
Security.ModifyAccessRule(AccessControlModification.Set, AccessRule,
out Result); if (!Result) return false; //老是容許再目錄上進行對象繼承 const InheritanceFlags iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit; //爲繼承關係添加訪問規則 AccessRule = new FileSystemAccessRule(user, Rights,iFlags,PropagationFlags.InheritOnly,AccessControlType.Allow); Security.ModifyAccessRule(AccessControlModification.Add, AccessRule, out Result); if (!Result) return false; Info.SetAccessControl(Security);//將 FileSecurity 對象所描述的訪問控制列表 (ACL) 項應用於當前 FileStream 對象所描述的文件。 return true; }

 

下面詳細的介紹一下比較重要的幾個方法,第一個:app

1、 public FileSystemAccessRule( string identity, FileSystemRights fileSystemRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)ide

定義訪問規則,參數以下:學習

identity   
  Type:     System.String
  The name of a user account. (帳戶名)
fileSystemRights
   Type:     System.Security.AccessControl.FileSystemRights
  One of the FileSystemRights values that specifies the type of operation associated with the access rule. (與訪問規則相關聯的操做類型)
inheritanceFlags
    Type:     System.Security.AccessControl.InheritanceFlags
  One of the InheritanceFlags values that specifies how access masks are propagated to child objects.
  (CSDN上解釋的是「該值指示如何將訪問掩碼傳播到子對象」,個人理解是 該值規定是將繼承規則做用在文件夾上仍是文件上)
propagationFlags
    Type:     System.Security.AccessControl.PropagationFlags
  One of the PropagationFlags values that specifies how Access Control Entries (ACEs) are propagated to child objects.
  (CSDN上解釋的是「該值指定如何將訪問控制項 (Ace) 傳播到子對象」,propagationFlags能起做用的前提是inheritanceFlags不爲None)
type
    Type:     System.Security.AccessControl.AccessControlType
  One of the AccessControlType values that specifies whether to allow or deny the operation.(容許仍是拒絕)

第一個參數是帳戶名,第二個是操做類型,操做類型對應的有如下:ui

("AppendData", "附加數據");
("ChangePermissions", "更改權限");
("CreateDirectories", "建立文件夾/附加數據");
("CreateFiles", "建立文件/寫入數據");
("Delete", "刪除");
("DeleteSubdirectoriesAndFiles", "刪除子文件夾及文件");
("ExecuteFile", "執行文件");
("FullControl", "徹底控制");
("ListDirectory", "列出文件夾/讀取數據");
("Modify", "修改");
("Read", "讀取");
("ReadAndExecute", "讀取和執行");
("ReadAttributes", "讀取屬性");
("ReadData", "讀取數據");
("ReadExtendedAttributes", "讀取擴展屬性");
("ReadPermissions", "讀取權限");
("Synchronize", "同步");
("TakeOwnership", "更改文件(夾)全部者");
("Traverse", "執行程序");
("Write", "寫入");
("WriteAttributes", "寫入屬性");
("WriteData", "寫入數據");
("WriteExtendedAttributes", "寫入擴展屬性");

第三四個參數比較難懂,而且他兩個應該組合起來應用。一個是inheritanceFlags(ContainerInherit,None,ObjectInherit),另外一個是propagationFlags(InheritOnly,None,NoPropagateInherit),這兩枚舉都有三個值,都具備容許其成員值的按位組合的 FlagsAttribute 特性,propagationFlags能起做用的前提是inheritanceFlags不爲None。spa

下面是我總結的經常使用的枚舉組合:.net

 

對應到windows界面操做上後,以下圖所示:ssr

第五個參數規定該訪問規則的類型是 容許仍是拒絕。3d

 

再看一下另外一個方法:

二 、public virtual bool ModifyAccessRule( AccessControlModification modification, AccessRule rule, out bool modified)

修改訪問規則,參數以下:

modification
    Type:     System.Security.AccessControl.AccessControlModification
  The modification to apply to the DACL.(包括Add、Remove、RemoveAll、RemoveSpecific、Reset、Set
rule
    Type:     System.Security.AccessControl.AccessRule
  The access rule to modify.(訪問規則)
modified
    Type:     System.Boolean
  true
if the DACL is successfully modified; otherwise, false.(指示成功仍是失敗)

返回值
Type:     System.Boolean
true
if the DACL is successfully modified; otherwise, false.

 最後利用SetAccessControl將FileSecurity 對象所描述的訪問控制列表 (ACL) 項應用於當前 FileStream 對象所描述的文件。

 

 

最後貼上我本身寫的一個類,可根據本身須要加以修改。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Security.AccessControl;
  5 using System.IO;
  6 using System.Security.Principal;
  7 
  8 namespace subServer
  9 {
 10     class WinFileAccessHelper
 11     {
 12         private enum MyRights
 13         {
 14             ChangePermissions,
 15             CreateDirectories,
 16             CreateFiles,
 17             Delete,
 18             DeleteSubdirectoriesAndFiles,
 19             ExecuteFile,
 20             FullControl,
 21             ListDirectory,
 22             Modify,
 23             Read,
 24             ReadAndExecute,
 25             ReadAttributes,
 26             ReadData,
 27             ReadExtendedAttributes,
 28             ReadPermissions,
 29             Synchronize,
 30             TakeOwnership,
 31             Traverse,
 32             Write,
 33             WriteAttributes,
 34             WriteData,
 35             WriteExtendedAttributes
 36         };
 37 
 38         public enum MyEffectRange//做用範圍
 39         {
 40             OnlyThisFolder,             // 僅做用於此文件夾
 41 
 42             ThisAndAllChildFolder,      // 此文件夾和子文件夾(包括子文件夾下的全部文件夾)
 43             OnlyAllChildFolder,         // 只有子文件夾(包括子文件夾下的全部文件夾,但不包括此文件夾)
 44             ThisAndOnlyChildFolder,     // 此文件夾和子文件夾(不包括子文件夾下的文件夾)
 45 
 46             ThisAndALLFiles,            // 此文件夾和文件(包括子文件夾下的全部文件)
 47             OnlyAllFiles,               // 只有文件(包括子文件夾下的全部文件,但不包括此文件夾)
 48             ThisAndOnlyChildFiles,      // 此文件夾和此文件夾下的文件(不包括子文件夾和子文件夾下的文件)
 49 
 50             ThisAndAllFolderFiles,      // 此文件夾、子文件夾和文件(包括文件夾下的全部文件夾和文件)
 51             OnlyAllChildFolderFiles,    // 子文件夾和文件(包括文件夾下的全部文件夾和文件,不包括此文件夾)
 52             ThisAndOnlyChildFolderFiles // 此文件夾、此文件夾下的文件 和子文件夾(不包括子文件夾下的文件夾和文件)
 53         };
 54 
 55         public struct InheritPropPair
 56         {
 57             public InheritPropPair(InheritanceFlags inher, PropagationFlags pro)
 58             {
 59                 inherit = inher;
 60                 propagation = pro;
 61             }
 62             public InheritanceFlags inherit;
 63             public PropagationFlags propagation; 
 64         }
 65 
 66         /// <summary>
 67         /// 經過做用範圍得到InheritPropPair
 68         /// </summary>
 69         /// <param name="range"></param>
 70         /// <param name="pair"></param>
 71         /// <returns></returns>
 72         public static bool getInheritPropPair(MyEffectRange range, out InheritPropPair pair)
 73         {
 74             bool isRight = true;
 75             InheritanceFlags inheritTmp = InheritanceFlags.None;
 76             PropagationFlags propagationTmp = PropagationFlags.None;
 77 
 78             switch (range)
 79             {
 80                 case MyEffectRange.OnlyThisFolder:
 81                     inheritTmp = InheritanceFlags.None;
 82                     propagationTmp = PropagationFlags.None;
 83                     break;
 84 
 85                 case MyEffectRange.ThisAndAllChildFolder:
 86                     inheritTmp = InheritanceFlags.ContainerInherit;
 87                     propagationTmp = PropagationFlags.None;
 88                     break;
 89                 case MyEffectRange.OnlyAllChildFolder:
 90                     inheritTmp = InheritanceFlags.ContainerInherit;
 91                     propagationTmp = PropagationFlags.InheritOnly;
 92                     break;
 93                 case MyEffectRange.ThisAndOnlyChildFolder:
 94                     inheritTmp = InheritanceFlags.ContainerInherit;
 95                     propagationTmp = PropagationFlags.NoPropagateInherit;
 96                     break;
 97 
 98                 case MyEffectRange.ThisAndALLFiles:
 99                     inheritTmp = InheritanceFlags.ObjectInherit;
100                     propagationTmp = PropagationFlags.None;
101                     break;
102                 case MyEffectRange.OnlyAllFiles:
103                     inheritTmp = InheritanceFlags.ObjectInherit;
104                     propagationTmp = PropagationFlags.InheritOnly;
105                     break;
106                 case MyEffectRange.ThisAndOnlyChildFiles:
107                     inheritTmp = InheritanceFlags.ObjectInherit;
108                     propagationTmp = PropagationFlags.NoPropagateInherit;
109                     break;
110 
111                 case MyEffectRange.ThisAndAllFolderFiles:
112                     inheritTmp = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
113                     propagationTmp = PropagationFlags.None;
114                     break;
115                 case MyEffectRange.OnlyAllChildFolderFiles:
116                     inheritTmp = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
117                     propagationTmp = PropagationFlags.InheritOnly;
118                     break;
119                 case MyEffectRange.ThisAndOnlyChildFolderFiles:
120                     inheritTmp = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
121                     propagationTmp = PropagationFlags.NoPropagateInherit;
122                     break;
123 
124                 default:
125                     Console.WriteLine("輸入參數不正確");
126                     isRight = false;
127                     break;
128             }
129             pair.inherit = inheritTmp;
130             pair.propagation = propagationTmp;
131             return isRight;
132         }
133 
134         /// <summary>
135         /// 爲指定用戶組,受權目錄指定訪問權限
136         /// </summary>
137         /// <param name="user">用戶組,如Users/Everyone</param>
138         /// <param name="folderOrFile">目錄或文件路徑</param>
139         /// <param name="rights">FileSystemRights類型的權限,可疊加</param>
140         /// <param name="pair">由做用範圍獲得的繼承和傳播方式pair</param>
141         /// <param name="accessType">AccessControlType類型的參數,有Allow/Deny</param>
142         /// <param name="isDelExistingAccess">是否刪除該用戶已有的權限控制</param>
143         /// <returns></returns>
144         public static bool SetAccess(string user, string folderOrFile, FileSystemRights rights, InheritPropPair pair,AccessControlType accessType)
145         {
146             try
147             {
148                 if (!Directory.Exists(folderOrFile) && !File.Exists(folderOrFile))
149                     return false;
150 
151                 var Info = new DirectoryInfo(folderOrFile);
152                 var Security = Info.GetAccessControl(AccessControlSections.Access);
153                 bool Result;
154                 var AccessRule = new FileSystemAccessRule(user, rights, pair.inherit, pair.propagation, accessType);
155 
156                 Security.ModifyAccessRule(AccessControlModification.Set, AccessRule, out Result);
157                 if (!Result)
158                     return false;
159 
160                 Info.SetAccessControl(Security);
161                 return true;
162             }
163             catch(Exception ex)
164             {
165                 System.Windows.Forms.MessageBox.Show(ex.ToString(), "設置權限錯誤");
166                 return false;
167             }
168         }
169 
170         /// <summary>
171         /// 刪除權限
172         /// </summary>
173         /// <param name="user"></param>
174         /// <param name="folderOrFile"></param>
175         /// <param name="rights"></param>
176         /// <param name="pair"></param>
177         /// <param name="accessType"></param>
178         /// <returns></returns>
179         public static bool RemoveAccess(string user, string folderOrFile, FileSystemRights rights, InheritPropPair pair, AccessControlType accessType)
180         {
181             try
182             {
183                 if (!Directory.Exists(folderOrFile) && !File.Exists(folderOrFile))
184                     return false;
185 
186                 var Info = new DirectoryInfo(folderOrFile);
187                 var Security = Info.GetAccessControl(AccessControlSections.Access);
188                 bool Result;
189                 var AccessRule = new FileSystemAccessRule(user, rights, pair.inherit, pair.propagation, accessType);
190 
191                 Security.ModifyAccessRule(AccessControlModification.Remove, AccessRule, out Result);
192                 if (!Result)
193                     return false;
194 
195                 Info.SetAccessControl(Security);
196                 return true;
197             }
198             catch (Exception ex)
199             {
200                 System.Windows.Forms.MessageBox.Show(ex.ToString(), "刪除權限錯誤");
201                 return false;
202             }
203         }
204        
205         /// <summary>
206         /// 刪除全部「拒絕」權限,只能刪除自身設置的訪問控制權限,不能刪除繼承得來的權限。若是想刪除繼承的權限,請先調用DenyInheritAccess()
207         /// </summary>
208         /// <param name="folderOrFile">文件夾或文件</param>
209         /// <returns></returns>
210         public static bool RemoveAllDenyAccess(string folderOrFile)
211         {
212             try
213             {
214                 if (!Directory.Exists(folderOrFile) && !File.Exists(folderOrFile))
215                     return false;
216 
217                 var Info = new DirectoryInfo(folderOrFile);
218                 var Security = Info.GetAccessControl(AccessControlSections.Access);
219                 bool Result;
220 
221                 foreach (FileSystemAccessRule rule in Security.GetAccessRules(true, true, typeof(NTAccount)))
222                 //foreach (FileSystemAccessRule rule in Security.GetAccessRules(true, true, typeof(SecurityIdentifier)))
223                 {
224                     //NTAccount時輸出:容許 BUILTIN\Administrators---- FullControl 
225                     //SecurityIdentifier時輸出:容許 S-1-5-32-544---- FullControl
226                     //Console.WriteLine("{0} {1}---- {2}",
227                     //    rule.AccessControlType == AccessControlType.Allow ? "容許" : "拒絕",
228                     //    rule.IdentityReference.ToString(),
229                     //    rule.FileSystemRights
230                     //    );
231                     if (rule.AccessControlType == AccessControlType.Deny)
232                     {
233                         Security.ModifyAccessRule(AccessControlModification.Remove, rule, out Result);
234                         if (!Result)
235                             return false;
236                         Info.SetAccessControl(Security);
237   //                      System.Windows.Forms.MessageBox.Show(folderOrFile+"Deny result"+Result);
238                     }
239                 }
240 
241                 return true;
242             }
243             catch (Exception ex)
244             {
245                 System.Windows.Forms.MessageBox.Show(ex.ToString(), "刪除權限錯誤");
246                 return false;
247             }
248         }
249 
250         /// <summary>
251         /// 刪除繼承得來的訪問權限
252         /// </summary>
253         /// <param name="folderOrFile">文件夾或文件</param>
254         /// <param name="preserveInheritance">是否保留繼承得來的訪問權限</param>
255         /// <returns></returns>
256         public static bool DenyInheritAccess(string folderOrFile, bool preserveInheritance)
257         {
258             try
259             {
260                 if (!Directory.Exists(folderOrFile) && !File.Exists(folderOrFile))
261                     return false;
262                 var Info = new DirectoryInfo(folderOrFile);
263                 var Security = Info.GetAccessControl(AccessControlSections.Access);
264                 Security.SetAccessRuleProtection(true, preserveInheritance);
265                 Info.SetAccessControl(Security);
266                 return true;
267             }
268             catch (Exception ex)
269             {
270                 System.Windows.Forms.MessageBox.Show(ex.ToString(), "禁用繼承權限錯誤");
271                 return false;
272             }
273         }
274     }
275 }
目錄訪問控制類

若是想進一步瞭解關於訪問控制的詳細介紹,能夠參考http://www.cnblogs.com/xuanhun/archive/2012/06/23/2559576.html

相關文章
相關標籤/搜索