5. 资源的访问控制

在操作系统中,资源(如文件和注册表键,以及命名管道的句柄)都使用访问控制列表(ACL)来保护。下图显示了这个映射的结构。资源有一个关联的安全描述符。安全描述符包含了资源拥有者的信息,并引用了两个访问控制列表:自由访问控制列表(Discretionary Access Control List,DACL)和系统访问控制列表(System Access Control List,SACL)。DACL用来确定谁有访问权;SACL用来确定安全事件日志的审核规则。ACL包含一个访问控制项(Access Control Entries,ACE)列表。ACE包含类型、安全标识符和权限。在DACL中,ACE的类型可以是允许访问或拒绝访问。可以用文件设置和获得的权限是创建、读取、写入、删除、修改、改变许可和获得拥有权。

读取和修改访问控制的类在System.Security.AccessControl名称空间中。下面的程序说明了如何从文件中读取访问控制列表。

FileAccessControl实例应用程序使用了如下依赖项和名称空间:

 依赖项

System.IO.FileSystem

System.IO.FileSystem.AccessControl

名称空间

System

System.IO

System.Security.AccessControl

System.Security.Principal

警告:

访问控制API只能用于Windows,不能用于Linux或Mac。System.IO.FileSystem.AccessControl API是Windows上资源管理的一部分

FileStrem类定义了GetAccessControl()方法,该方法返回一个FileSecurity对象。FileSecurity是一个.NET类,它表示文件的安全描述符。FileSecurity类派生自基类ObjectSecurity、CommonObjectSecurity、NativeObjectSecurity和FileSystemSecurity。其他表示安全描述符的类有CryptoKeySecurity、EventWaitHandleSecurity、MutexSecurity、RegistrySecurity、SemaphoreSecurity、PipeSecurity和ActiveDirectorySecurity。所有这些对象都可以使用访问控制列表来保护。一般情况下,对应的.NET类定义了GetAccessControl()方法,返回相应的安全类;例如,Mutex.GetAccessControl()方法返回一个MutexSecurity类,PipeStream.GetAccessControl()方法返回一个PipeSecurity类。

FileSecurity类定义了读取、修改DACL和SACL的方法。GetAccessRules()方法以AuthorizationRuleCollection类的形式返回DACL。要访问SACL,可以使用GetAuditRules方法。

在GetAccessRules()方法中,可以确定是否应使用继承的访问规则(不仅仅使用对象直接定义的访问规则)。最后一个参数定义了应返回的安全标识符的类型。这个类型必须派生自基类IdentityReference。可能的类型有NTAccout和SecurityIdentifier。这两个类都表示用户或组。NTAccout类按名称查找安全对象,SecurityIdentifier类按唯一的安全标识符查找安全对象。

返回的AuthorizationRuleCollection包含AuthorizationRule对象。AuthorizationRule对象是ACE的.NET表示。在这里的例子中,因为访问一个文件,所以AuthorizationRule对象可以强制转换为FileSystemAccessRule类型。在其他资源的ACE中,存在不同的.NET表示,例如MutexAccessRule和PipeAccessRule。在FileSystemAccessRule类中,AccessControlType、FileSystemRights和IdentityReference属性返回ACE的相关信息:

    class Program
    {
        static void Main(string[] args)
        {
            string fileName = null;
            //if (args.Length == 0)
            //{
            //    return;
            //}
            //fileName = args[0];
            fileName = @"C:\Users\singh\Desktop\appsettings.txt";
            using (FileStream stream = File.Open(fileName,FileMode.Open))
            {
                FileSecurity securityDescriptor = stream.GetAccessControl();
                AuthorizationRuleCollection rules = securityDescriptor.GetAccessRules(true,true,typeof(NTAccount));
                foreach (AuthorizationRule rule in rules)
                {
                    var fileRule = rule as FileSystemAccessRule;
                    Console.WriteLine($"Access type: {fileRule.AccessControlType}");
                    Console.WriteLine($"Rights: {fileRule.FileSystemRights}");
                    Console.WriteLine($"Identity: {fileRule.IdentityReference.Value}");
                    Console.WriteLine();
                }
            }
        }
    }

运行应用程序,并传递一个文件名,就可以看到文件的访问控制列表。这里的输出列出了管理员和系统的全部控制权限、通过身份验证的用户的修改权限,以及属于Users组的所有用户的读取和执行权限。

Access type: Allow
Rights: FullControl
Identity: NT AUTHORITY\SYSTEM

Access type: Allow
Rights: FullControl
Identity: BUILTIN\Administrators

Access type: Allow
Rights: FullControl
Identity: DESKTOP-EUK91RH\singh

设置访问权限非常类似于读取访问权限。要设置访问权限,几个可以得到保护的资源类提供了SetAccessControl()和ModifyControl()方法。这里的示例代码调用给FileInfo类定义的SetAccessControl()扩展方法,以修改文件的访问控制列表。给这个方法传递一个FileSecurity对象。FileSecurity对象用FileSystemAccessRule对象填充。这里列出的访问规则拒绝Sales组的写入访问权限,给Everyone组提供了读取访问权限,并给Developers组提供了全部控制权限。

注意:

只有定义了Windows组Sales和Developers以及Everyone,这个程序才能在系统上运行。可以修改程序,使用自己环境下的可用组

        private static void WriteAcl(string fileName)
        {
            //使用自己的用户组:Guests、Device Owners、Users
            var guestsIdentity = new NTAccount("Guests");
            var deviceOwnersIdentity = new NTAccount("Device Owners");
            var usersIdentity = new NTAccount("Users");

            var guestsAce = new FileSystemAccessRule(guestsIdentity,FileSystemRights.Write,AccessControlType.Deny);
            var usersAce = new FileSystemAccessRule(usersIdentity,FileSystemRights.Read,AccessControlType.Allow);
            var deviceOwnersAce = new FileSystemAccessRule(deviceOwnersIdentity,FileSystemRights.FullControl,AccessControlType.Allow);

            var securityDescriptor = new FileSecurity();
            securityDescriptor.SetAccessRule(guestsAce);
            securityDescriptor.SetAccessRule(usersAce);
            securityDescriptor.SetAccessRule(deviceOwnersAce);
            //using (var stream = new FileStream(fileName, FileMode.Open))//会出现异常: UnauthorizedAccessException
            //{
            //    try
            //    {
            //        stream.SetAccessControl(securityDescriptor);
            //    }
            //    catch (UnauthorizedAccessException ex)
            //    {
            //        Console.WriteLine(ex.Message);
            //    }                
            //}
            FileInfo file = new FileInfo(fileName);
            file.SetAccessControl(securityDescriptor);
        }

注意:

打开该文件属性窗口,在安全选项卡,列出了改变后的访问控制列表,可以验证访问规则。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值