AccessControl 命名空间 结构图

解说:

DirectorySecurity=目录ACL
FileSecurity=文件ACL
FileSystemAuditRule=目录和文件中SACL中的ACE
FileSystemAccessRule=目录和文件中DACL中的ACE
GetAccessControl=ACL(AccessControlList)The security descriptors of all the access control sections of the directory.

DirectorySecurity类和FileSecurity类是对基础Microsoft Windows文件安全系统的抽象。----注:本文部分内容改编自《.NET安全揭秘》

FileSystemAccessRule和FileSystemAuditRule 类是对组成DACL和SACL的访问控制项(ACE)的抽象----注:本文部分内容改编自《.NET安全揭秘》

案例1、window平台的ACL、 ACE操作实例

給文件夹添加访问控制项(ACE:), 要以管理员的方式运行vs2022,这样才能正确的添加sACE,特权。

新建一个ACL

第一方式,新建一个ACL,然后赋值给文件,这种方式会覆盖原来ACL的列表。并且对文件的sACE,dACE经行增删改

using System.Diagnostics;
using System.Security.AccessControl;
using System.Security.Principal; //把桌面设置未当前目录
Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop ));
//用n #region 添加ACE //新建ACE ,ACE FileSystemAuditRule SACE = new("TestAccount", FileSystemRights.FullControl, AuditFlags.Success);
FileSystemAuditRule SACE2 = new(WindowsIdentity.GetCurrent().Name, FileSystemRights.Read, AuditFlags.Failure);
FileSystemAuditRule SACE3 = new("TestAccount", FileSystemRights.Modify, AuditFlags.Failure); FileSystemAccessRule DACE = new("TestAccount" ,FileSystemRights.FullControl,AccessControlType.Deny);
FileSystemAccessRule DACE2 = new(WindowsIdentity.GetCurrent().Name, FileSystemRights.Read|FileSystemRights.Write,InheritanceFlags.None,PropagationFlags.None, AccessControlType.Allow);
FileSystemAccessRule DACE3 = new("TestAccount", FileSystemRights.Read , AccessControlType.Allow); //关联桌面的已经存在的CSD文件夹
DirectoryInfo dir = new ("CSD"); //获取文件的ACL
DirectorySecurity ACL=dir.GetAccessControl(); //将sACEs、dACLs加入ACL
ACL.AddAccessRule(DACE);
ACL.AddAccessRule(DACE2);
ACL.AddAccessRule(DACE3); ACL.AddAuditRule(SACE);
ACL.AddAuditRule(SACE2);
ACL.AddAuditRule(SACE3); dir.SetAccessControl(ACL); //获取文件夹SACL权限
DirectorySecurity AClwithAudit = dir.GetAccessControl(AccessControlSections.Audit); foreach (FileSystemAuditRule item in AClwithAudit.GetAuditRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(item.AuditFlags); }
Console.Read(); //获取文件夹DACL权限
DirectorySecurity AClwithAccess = dir.GetAccessControl(AccessControlSections.Access); foreach (FileSystemAccessRule item in AClwithAccess.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(item.AccessControlType );
}
#endregion //removeDACE("TestAccount","CSD",AccessControlType.Deny);
RemoveAllDACE("TestAccount","CSD");

/// <summary>
/// 删除指定用户的文件夹dACE
/// </summary>
static void RemovedDACE(string username,string fielname, AccessControlType Type)
{ DirectoryInfo dir = new (fielname);
DirectorySecurity AClwithAccess = dir.GetAccessControl(AccessControlSections.Access); foreach (FileSystemAccessRule dace in AClwithAccess.GetAccessRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(dace.IdentityReference.Value); if (dace.AccessControlType == Type && dace.IdentityReference.Value == @$"{Environment.UserDomainName}\{username}")
{ AClwithAccess.ModifyAccessRule(AccessControlModification.Remove, dace, out bool ivalue);
if (ivalue == true)
{ dir.SetAccessControl(AClwithAccess);
Console.WriteLine("移除成功"); } }
} } /// <summary>
/// 删除指定用户在指定文件夹的所有D-ACE权限
/// </summary>
static void RemoveAllDACE(string username,string filename)
{ DirectoryInfo dir = new (filename);
DirectorySecurity AClwithAccess = dir.GetAccessControl(); AClwithAccess.PurgeAccessRules(new NTAccount(@$"{Environment.UserDomainName}\{username}"));
dir.SetAccessControl(AClwithAccess);
Console.WriteLine("移除成功");
} /// <summary>
/// 删除指定用户的文件夹sACE
/// </summary> static void RemovedSACE(string username, string fielname, AuditFlags Type)
{ DirectoryInfo dir = new(fielname);
DirectorySecurity AClwithAccess = dir.GetAccessControl(AccessControlSections.Access); foreach (FileSystemAuditRule sace in AClwithAccess.GetAuditRules(true, true, typeof(NTAccount)))
{
Console.WriteLine(sace.IdentityReference.Value); if (sace.AuditFlags == Type && sace.IdentityReference.Value == @$"{Environment.UserDomainName}\{username}")
{ AClwithAccess.ModifyAuditRule(AccessControlModification.Remove, sace, out bool ivalue);
if (ivalue == true)
{ dir.SetAccessControl(AClwithAccess);
Console.WriteLine("移除成功"); } }
} } /// <summary>
/// 删除指定用户在指定文件夹的所有S-ACE权限
/// </summary>
static void RemovedALLSACE(string username, string filename)
{ DirectoryInfo dir = new(filename);
DirectorySecurity AClwithAudit = dir.GetAccessControl(); AClwithAudit.PurgeAuditRules(new NTAccount(@$"{Environment.UserDomainName}\{username}"));
dir.SetAccessControl(AClwithAudit);
Console.WriteLine("移除成功");
}

下面详细的介绍一下比较重要的几个方法,第一个:

一、 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界面操作上后,如下图所示:

第五个参数规定该访问规则的类型是 允许还是拒绝。

现有的ACL上添加ACE

using System.Security.AccessControl;
using System.Security.Principal;
//把桌面设置未当前目录
Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop )); //新建ACE ,ACE的拥有者设置成当前 操作系统用
FileSystemAuditRule SACE=new FileSystemAuditRule(WindowsIdentity.GetCurrent().Name,FileSystemRights.FullControl,AuditFlags.Success);
FileSystemAccessRule DACE = new FileSystemAccessRule(WindowsIdentity.GetCurrent().Name,FileSystemRights.FullControl,AccessControlType.Deny);
FileSystemAccessRule DACE2 = new FileSystemAccessRule(WindowsIdentity.GetCurrent().Name, FileSystemRights.Read|FileSystemRights.Write,InheritanceFlags.None,PropagationFlags.None, AccessControlType.Allow); //新建文件,并且ACL把文件添加到目录上。会和原来的ACL列表合并
DirectoryInfo dir = new DirectoryInfo("CSD");
DirectorySecurity sd=dir.GetAccessControl();
sd.AddAccessRule(DACE);
sd.AddAccessRule(DACE2); dir.SetAccessControl(sd);

遍历ACL中的ACE

遍历ACL中的ACE

            AuthorizationRuleCollection rules = fileAcl.GetAccessRules(true, true, typeof(NTAccount));
// AuthorizationRule Rule = rules[0];
foreach (FileSystemAccessRule rule in rules)
{
if(rule.IdentityReference.Value.CompareTo("Users")==0)
{
fileAcl.RemoveAccessRule(rule);
}
}

文件夹权限继承控制

DirectorySecurity ss = di.GetAccessControl();

ss.SetAccessRuleProtection(true,true);//这个是保护acl,防止继承,true为启用保护,这样就不会继承父类了,第二项是否保留已经继承的。

获取ACE的掩码

using System.Security.AccessControl;
using System.IO;
using System.Security.Principal;
using System.Reflection; Directory.SetCurrentDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
DirectoryInfo di = new("CSD"); DirectorySecurity ss = di.GetAccessControl(); Console.WriteLine(ss.GetGroup(typeof(NTAccount)));
foreach (FileSystemAccessRule ace in ss.GetAccessRules(true,true,typeof(NTAccount)))
{
Type getMask = typeof(FileSystemAccessRule);
PropertyInfo propertyInfo = getMask.GetProperty("AccessMask", BindingFlags.Instance|BindingFlags.NonPublic | BindingFlags.GetProperty);
int Mask =int.Parse( propertyInfo.GetValue(ace, null).ToString()); Console.WriteLine($"AccessControltype:{ace.FileSystemRights} AcessMask:{ Convert.ToString(Mask, 2).PadLeft(32,'0') }"); }

案例2、通用平台的ACL ACE操作实例

这些方式是操作SD类型的通用方式(与底层的Windows资源的类型无关),.NET提供了如下类型:

1. 表示SD
  • System.Security.AccessControl.GenericSecurityDescriptor
  • System.Security.AccessControl.CommonSecurityDescriptor
  • System.Security.AccessControl.RawSecurityDescriptor
2. 表示ACL、DACL与SACL
  • System.Security.AccessControl.GenericAcl
  • System.Security.AccessControl.CommonAcl
  • System.Security.AccessControl.DescretionaryAcl
  • System.Security.AccessControl.SystemAcl
  • System.Security.AccessControl.RawAcl
3. 表示一个ACE
  • System.Security.AccessControl.GenericAce
  • System.Security.AccessControl.CustomAce
  • System.Security.AccessControl.KnownAce
  • System.Security.AccessControl.CompoundAce
  • System.Security.AccessControl.QualifiedAce
  • System.Security.AccessControl.CommonAce
  • System.Security.AccessControl.ObjectAce

示例:创建一个SD,向其DACL中添加ACE并将其转化为一个代表Windows资源的特殊SD(此处为互斥体)。

using System;
using System.Security.AccessControl;
using System.Security.Principal;
class Program {
static void Main() {
//创建一个新的SD
CommonSecurityDescriptor csd = new CommonSecurityDescriptor(false, false, string.Empty);
DiscretionaryAcl dacl = csd.DiscretionaryAcl;
//向DACL中添加ACE
dacl.AddAccess(
AccessControlType.Allow, // 枚举Allow、Deny.
WindowsIdentity.GetCurrent().Owner,
(int)MutexRights.TakeOwnership | (int)MutexRights.Synchronize,
InheritanceFlags.None, // 禁用ACE继承
PropagationFlags.None); string sSDDL = csd.GetSddlForm( AccessControlSections.Owner ); MutexSecurity mutexSec = new MutexSecurity();
mutexSec.SetSecurityDescriptorSddlForm( sSDDL );
AuthorizationRuleCollection aces = mutexSec.GetAccessRules(true, true, typeof(NTAccount));
foreach ( AuthorizationRule ace in aces ) {
if (ace is MutexAccessRule) {
MutexAccessRule mutexAce = (MutexAccessRule)ace;
Console.WriteLine( "-->SID : " + mutexAce.IdentityReference.Value );
Console.WriteLine( "访问权限类型:" + mutexAce.AccessControlType.ToString());
if (0xffffffff == (uint) mutexAce.MutexRights)
Console.WriteLine( "拥有所有权限" );
else
Console.WriteLine( "权限: " + mutexAce.MutexRights.ToString());
}
}
}
}

最新文章

  1. BFC给我的帮助以及对hasLayout的认识
  2. angular中ng-model,返回数据,拆分数据,展示,名称相同,重新赋值会有冲突
  3. FileIOUtils.java
  4. Cisco IOS Debug Command Reference I through L
  5. OpenCV 连接 Android IP摄像头
  6. P1082 找朋友
  7. ASPNET中实现在线用户检测(使用后台守护线程)
  8. HDU-2552 三足鼎立
  9. Windows Azure 配置SSTP
  10. UML_行为图
  11. 转:批处理for命令详解
  12. Linux进程和线程的比較
  13. java模拟报文
  14. 使用Kubeadm部署Kubernetes1.14.1集群
  15. JS 获取图片标签和所有的图片中的src的正则表达式
  16. Concurrent包详解及使用场景
  17. mysql-5.7.19 压缩安装 设置密码
  18. JAVA开发微信支付-公众号支付/微信浏览器支付(JSAPI)
  19. # 20155224 课堂实践 MyOD
  20. Windows降权

热门文章

  1. Servlet三种创建方式
  2. gin中绑定html复选框
  3. ping: Network is unreachable
  4. Abp 审计模块源码解读
  5. Java编程中标识符注意点以及注释
  6. Docker版本Jenkins的使用
  7. Java 自定义窗体(标题栏、窗体背景)
  8. 理解Laravel中的pipeline
  9. JVM收藏的文章
  10. 简单理解Zookeeper的Leader选举