.net 安全编程 阅读笔记

来源:互联网 发布:js input text change 编辑:程序博客网 时间:2024/05/21 10:26

一: 权限

    所谓权限, 既代码能否运行或访问一定资源的资格. 而所谓权限的制定, 则是制定一系列框架或对应关系, 从而定义什么样的代码, 或怎么运行的代码具有什么样的资格. dot net framework 包括CAS(code access security)这个重要的功能, 能为托管代码的操作和访问资源提供精细的控制. 使用CAS访问是基于代码表示而不是用户运行. 同时, CAS提供了一套灵活的可扩展框架, 既使用权限的对象来定义和强制执行代码的安全性. 权限对象可以实现以下目标:

    1. 当运行库载入程序集时, 它会为程序集分配权限对象, 该对象代表了运行库授予程序集的权力.

    2. 保护程序集想要调用的资源或代码, 即要求调用系统资源或代码的程序集具备一定的权限. 运行库在载入程序集时会授予每一个程序集一组权限对象, 当程序集的代码调用库成员时, 库就会使用权限对象来要求运行库保证调用的程序集具有同等权限.

 

运行库基于程序集标识来决定授予程序集哪组权限, 运行库使用两种不同的机制将证据转化成权限:

    1. 运行库通过比较基于 dot net 安全策略的程序集的证据,在一个名为策略解析的进程里来决定授予程序集哪组代码访问权限.

    2. 实现System.Security.Policy.IidentityPermissionFactory接口的任意宿主证据都会导致运行库授予程序集一个标识权限.该权限代表了证据的类型和值.

    当调用程序集时, 运行库载入程序集,计算其证据并决定授予它哪些权限, 同时,运行库还需要保证, 不仅即时调用方具有指定权限, 而且整个调用链也都具有必要的权限, 这样才能保证高权限代码不会被低权限代码调用从而执行它本来没有权限做的事情, 此时运行库将进入堆栈并检查权限.

 

编程代码访问的安全性.

    1. 强制性安全语句: 强制性安全语句出现在方法体或函数体中, 通常使用Demond()方法. 对于上面讲到的堆栈中的权限检查, 通常使用Assert, Deny 和PermitOnly方法. 强制性安全检查的语法大致如下:

  1. public void CreateFile()
  2. {
  3.  FileIOPermission perm = new FileIOPermission(
  4.  FileIOPermissionAccess.Write,@"C:/SomeFile.txt");
  5.  try{
  6.  perm.Demand();
  7.  }
  8.  catch(Exception ex)
  9.  {
  10.  //someting  
  11.  }
  12. }

    2. 声明性安全语句: 使用属性来声明安全语句. 对每一种代码访问和标识权限类而言, .net类库都包含了相应的属性类. 它们能表示该权限的声明性安全语法. 如FileIOPermission类的相应属性是FileIOPermissionAttribute. 同时对于属性的Attribute还可以省略. 声明性安全支持的操作选择比强制性安全支持的要多一些. 具体例子如下:

  1. [FileIOPermission(SecurityAction.Demand,Write=@"C:/SomeFile.txt")]
  2. public void CreateFile(){
  3. //content
  4. }

.NET 提供如下的代码访问权限类:

DBDataPermission: 这是一个抽象基类, 能为数据提供程序权限类的基本功能.

OdbcPermission: 通过ODBC数据提供程序来控制访问数据源.

OleDbPermission: 通过OLE DB数据提供程序来控制访问数据源.

OraclePermission: 通过Oracle数据提供程序来控制访问Oracle数据库.

SqlClientPermission: 通过SQL客户数据提供程序来控制访问Microsoft SQL Server数据库.

EventLogPermission: 控制对Windows事件日志的访问.

PerformanceCounterPermission: 控制对Windows性能计数器的访问.

DirectoryServicesPermission:控制对目录服务的访问, 如Active Directory.

PrintingPermission:控制对打印机的访问.

DnsPermission: 控制对基于网络的域名服务器的访问.

WebPermission: 控制对Internet资源的访问.

SocketPermission: 控制对基于套接字的网络通信的访问.

MessageQueuePermission:控制对Microsoft消息列的访问.

EnvironmentPermission: 控制对读入,创建和改变环境变量的访问.

FileDialogPermission: 通过限制标准Windows文件对话框的可访问性机器功能来控制访问文件和文件夹.

FileIOPermission: 通过限制创建,改变或删除文件或文件夹来控制访问本地硬盘.

IsolatedStoragePermission: 控制对隔离存储的访问.

ReflectionPermission: 控制对运行库提供的访问.

RegistryPermission: 控制对Windows注册表的访问.

ResourcePermissionBase: 一个抽象基类, 为Windows面向资源的权限类提供公共功能.

SecurityPermission: 控制对一组安全功能的访问, 该功能与应用程序域,策略,证据, 线程, 原则, 执行, 构造,.net远程配置, 序列化, 确认和非托管代码有关.

UIPermission:控制对操作用户界面和剪贴板的访问.

ServiceControllerPermission: 控制对Windows服务入口的访问.

AspNetHostingPermission(1.1): 控制对ASP.NET--宿主环境的访问.

 

此外, 每种标准代码访问权限类还存在完全限制状态和非完全限制状态.由PermissionState枚举确定. 其值为None时,表示完全限制状态, 即没有任何权限, 其值为Unrestricted时,表示非完全限制状态. 如非完全限制状态的FileIOPermission代表可以访问本地硬盘驱动的所有文件和目录.而完全限制的FileIOPermission则代表不能访问它们. 不过值得注意的是, SecurityPermission 的Unrestricted设置无效.

 

编程权限集

当实现代码的CAS功能的时候, 通常可能会用到不止一个权限,这个时候,可以考虑应用编程权限集.PermissionSet. 通过AddPermisson方法,添加需要的权限, 之后,可以调用PermissionSet的Demand方法提出安全要求.它内部会调用Permission的Union方法,合成一个之后,再调用其Demand方法.此外,利用PermissionSet还可以应用集合的并与交去计算两个PermissionSet之间的权限.

 

编程权限请求

简单来说, 即写在程序集中, 希望运行库能够给予的权限.当运行库载入一个程序集时,它会计算权限的请求, 并使用声明性安全语法来表示该请求, 因为权限请求定义了程序集的安全要求,因此必须使用程序集范围属性来声明. 这并不能改变程序集本身的权限,但是可以提供很多便利,如可以方便的让用户或安全管理员查看程序集需要的权限(Permview.exe),以便作出必要部署. 权限请求分别被SecurityAction枚举所代表:RequestMinimum, RequestOptional和RequestRefuse.

    1. 最小权限请求 RequestMinimum, 如果想要编写能访问偶组权限的代码来实现正确的功能, 最好的办法就是给程序集配置最小权限请求, 特别是当代码要求的权限不是默认安全策略通常授予的权限的时候.配置方法如下:

  1. [assembly:FileIOPermission(SecurityAction.RequestMinimum,Read=@"c:/config")]
  2. [assembly:FileIOPermission(SecurityAction.RequestMinimum,All=@"c:/development")]

以上代码示范了如何申请最小权限保证读取C:/config和对C:/development目录的完全访问.

    2. 可选权限请求 RequestOptional. 该请求指定了最大权限组, 尽管有安全策略配置,运行库也应该授予程序集最大权限组, 如果不能授予RequestOptional语句指定的所有权限,运行库也能被载入, 但是运行库绝不会授予比制定权限更多的权限.

    3. 拒绝权限 RequestRefuse. 保证指定的权限不会被授予程序集. 以下方法是用一个非限制性的FileIOPermission来拒绝访问所有的文件及文件夹.

  1. [assembly:FileIOPermission(SecurityAction.RequestRefuse,Unrestricted=true)]

除了Demand之外, LinkDemands和InheritanceDemand也可以执行权限请求, 此处不再详细介绍.他们都可以应用到类或个体功能性成员如方法属性和事件中.如果使用声明性语法在类声明上制定了一个Demand, 每个类成员都会被强制执行同样的Demand, 为了重写个体成员的Demand, 只需在其上简单制定不同的Demand即可.

 

操作堆栈步

在某些实例中, 可能需要使用重写堆栈步的方法来改变默认的堆栈对于安全的相应方式.CAS支持三种不同的堆栈步重写方法:Assert, Deny和PermitOnly.

 

 

 

 

 

原创粉丝点击