.NET 控制Windows文件和目录访问权限研究(FileSystemAccessRule)
前一段时间学习了.net 控制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; }
下面详细的介绍一下比较重要的几个方法,第一个:
一、 public FileSystemAccessRule( string identity, FileSystemRights fileSystemRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
定义访问规则,参数如下:
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.(允许还是拒绝)
第一个参数是账户名,第二个是操作类型,操作类型对应的有以下:
("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。
下面是我总结的常用的枚举组合:
对应到windows界面操作上后,如下图所示:
第五个参数规定该访问规则的类型是 允许还是拒绝。
再看一下另一个方法:
二 、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