zoukankan      html  css  js  c++  java
  • .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时输出:允许 BUILTINAdministrators---- 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

  • 相关阅读:
    python自动化测试_6
    python自动化测试_5
    python自动化测试_4
    python自动化测试_3
    第一次个人编程作业
    第一次博客作业
    HangOver
    CSS实现动画特效导航栏
    CSS伪类整理笔记
    JavaScript闭包应用的整理
  • 原文地址:https://www.cnblogs.com/jaejaking/p/6344662.html
Copyright © 2011-2022 走看看