.NET(C#)中不同级别的安全透明代码对类型的影响
测试代码将测试一个方法和类默认在全部信任权限下和部分信任权限下的代码类型。
上面说的默认就是指未加入其他安全透明类型的特性。
代码类型可以是:
- 透明代码(Transparent Code)
- 关键代码(Critical Code)
- 可靠关键代码(Safe-critical Code)
测试这三项用到Type类和MethodInfo类中的IsSecurityTransparent,IsSecurityCritical和IsSecuritySafeCritical。注意这些属性不是从它们的共同基类MemberInfo中继承来的,因为某些MemberInfo比如属性(Property)是不属于可标识的。(但是属性的get和set可以,他们属于方法)
至于模拟部分受信任代码,我们通过创建一个给予部分权限的应用程序域然后在该应用程序域中执行代码。
测试代码框架:
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
class Program
{
static void Main()
{
//在全部受信任环境中运行
test();
//创建部分受信任应用程序域
var d = CreateSandbox();
//在部分受信任环境中运行
d.DoCallBack(() =>
{
test();
});
}
//测试方法
static void test()
{
if (AppDomain.CurrentDomain.IsFullyTrusted)
Console.WriteLine("全部受信任环境");
else
Console.WriteLine("部分受信任环境");
var method = MethodBase.GetCurrentMethod();
//判断方法
Console.WriteLine("默认方法 - 透明代码:{0,-5} 关键代码:{1,-5} 关键可靠代码:{2}",
method.IsSecurityTransparent,
method.IsSecurityCritical,
method.IsSecuritySafeCritical);
//判断类型
Console.WriteLine("默认类型 - 透明代码:{0,-5} 关键代码:{1,-5} 关键可靠代码:{2}\n",
method.DeclaringType.IsSecurityTransparent,
method.DeclaringType.IsSecurityCritical,
method.DeclaringType.IsSecuritySafeCritical);
}
//创建部分受信任环境
static AppDomain CreateSandbox()
{
//初始化空的权限集
var pset = new PermissionSet(PermissionState.None);
//添加Execution(执行)安全权限,没有此权限代码不会执行
pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
//添加其他权限
pset.AddPermission(new FileIOPermission(PermissionState.Unrestricted));
pset.AddPermission(new UIPermission(PermissionState.Unrestricted));
pset.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));
//必须设置AppDomainSetup.ApplicationBase,否则无法成功创建应用程序域
var adSetup = new AppDomainSetup();
adSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
var domain = AppDomain.CreateDomain("新的AppDomain",
null,
adSetup,
pset);
return domain;
}
}
在级别2中的结果是这样的(.NET 4.0后(包括4.0)CLR默认会使用级别2类型)
运行结果:
全部受信任环境
默认方法 - 透明代码:False 关键代码:True 关键可靠代码:False
默认类型 - 透明代码:False 关键代码:True 关键可靠代码:False
部分受信任环境
默认方法 - 透明代码:True 关键代码:False 关键可靠代码:False
默认类型 - 透明代码:True 关键代码:False 关键可靠代码:False
可以看出来,在级别2中,全部信任环境下,类型和成员都是关键代码。而部分信任环境下,它们都是透明代码。
如果手动在程序集中添加SecurityTransparent或AllowPartiallyTrustedCallers,则默认全部是透明代码:
using System.Security;
//[assembly: SecurityRules(SecurityRuleSet.Level1)]
//[assembly: SecurityCritical]
//.NET 4.0 +
[assembly: AllowPartiallyTrustedCallers]
//或者
[assembly: SecurityTransparent]
运行结果:
全部受信任环境
默认方法 - 透明代码:True 关键代码:False 关键可靠代码:False
默认类型 - 透明代码:True 关键代码:False 关键可靠代码:False
部分受信任环境
默认方法 - 透明代码:True 关键代码:False 关键可靠代码:False
默认类型 - 透明代码:True 关键代码:False 关键可靠代码:False
即便是全部信任环境,默认仍是透明代码。
在级别1中,首先得通过SecurityRules特性调节CLR运行程序集时采用级别1策略。
using System.Security;
[assembly: SecurityRules(SecurityRuleSet.Level1)]
然后再运行程序,结果:
全部受信任环境
默认方法 - 透明代码:False 关键代码:True 关键可靠代码:True
默认类型 - 透明代码:True 关键代码:False 关键可靠代码:False
部分受信任环境
默认方法 - 透明代码:True 关键代码:False 关键可靠代码:False
默认类型 - 透明代码:True 关键代码:False 关键可靠代码:False
在受限环境下,同级别1一样都一律视为透明代码。但在全部信任环境下,类型会被视为透明代码。但方法(或者其他类型成员)会被视为关键可靠代码(SecuritySafeCritical),由于是SecuritySafeCritical所以一定也属于SecurityCritical,因此关键代码也是True。
所以在级别1中,全部信任环境的代码是默认可以被部分受信任的代码访问的,如果你不想这样做,可以强命名整个程序集,级别1中强命名的程序集的所有公共成员会有隐式的全部权限的Link Demand,这样部分信任环境的程序集就无法访问了。当然手动添加Link Demand或者全部调用堆栈遍历(full demand)也可以。
在级别1中,SecurityTransparent特性和级别2一样,都会使整个程序集的全部成员成为透明代码。而AllowPartiallyTrustedCallers特性则不一样,它主要用来用在强命名的程序集中强制取消隐式的Link Demand。这样的话,程序集又可以被部分受信任代码所访问。如果想保护某些成员,可以手动添加SecurityCritical特性或者显示的Link Demand。
级别1中的SecurityCritical特性也有其他用处:
using System.Security;
[assembly: SecurityRules(SecurityRuleSet.Level1)]
[assembly: SecurityCritical]
如果这样使用,那么它和SecurityTransparent一样,只不过你可以手动在成员上再加SecurityCritical来指定它不是透明代码。
如果你想使整个程序集全部是关键代码的话(在级别2,默认就是这样的),使用SecurityCritical的Scope属性为Everything(在.NET 4.0中已废弃,由于.NET 4.0默认是使用级别2的):
using System.Security;
[assembly: SecurityRules(SecurityRuleSet.Level1)]
[assembly: SecurityCritical(SecurityCriticalScope.Everything)]
再运行代码,全部成员就是关键代码了(仅在全部权限下,部分权限下始终是透明代码)
全部受信任环境
默认方法 - 透明代码:False 关键代码:True 关键可靠代码:False
默认类型 - 透明代码:False 关键代码:True 关键可靠代码:False
.NET(C#)中不同级别的安全透明代码对类型的影响的更多相关文章
- DELPHI中如何让FORM窗体透明,只显示控件?
DELPHI中如何让FORM窗体透明,只显示控件?分享到: 对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理 回复次数:7largewanglargewanglargewang等级:Blank ...
- CSS透明代码
透明往往能产生不错的网页视觉效果,先奉上兼容主流浏览器的CSS透明代码: .transparent_class { filter:alpha(opacity=50); -moz-opacity:0.5 ...
- 使用Auto Layout中的VFL(Visual format language)--代码实现自动布局
使用Auto Layout中的VFL(Visual format language)--代码实现自动布局 2014-12-09 10:56 编辑: zhiwupei 分类:iOS开发 来源:机智的新手 ...
- Visio 2007中进行数据库建模时如何显示字段类型以及概念名称
关于在VISIO中进行数据库建模时如何显示字段类型,以及注释的 1 如何显示字段类型: 在visio菜单上--->点击数据库--->选项--->文档 打开后选择表这项,在上 ...
- C#开发中使用Npoi操作excel实例代码
C#开发中使用Npoi操作excel实例代码 出处:西西整理 作者:西西 日期:2012/11/16 9:35:50 [大 中 小] 评论: 0 | 我要发表看法 Npoi 是什么? 1.整个Exce ...
- 2.C#中通过委托Func消除重复代码
阅读目录 一:重复的代码 二:C#中通过委托Func消除重复代码 一:重复代码 public class Persion { public string Name { get; set; } ...
- Java中替换HTML标签的方法代码
这篇文章主要介绍了Java中替换HTML标签的方法代码,需要的朋友可以参考下 replaceAll("\\&[a-zA-Z]{0,9};", "").r ...
- 兼容主流浏览器的CSS透明代码
透明往往能产生不错的网页视觉效果下面是兼容主流浏览器的CSS透明代码.transparent_class { filter:alpha(opacity=50); -moz-opacity:0.5; ...
- 怎么知道RTL Schematic中的instance与哪段代码对应呢
2013-06-23 20:15:47 ISE综合后可以看到RTL Schematic,但我们知道在RTL编码时,要经常问自己一个问题“我写的这段代码会综合成什么样的电路呢”.对于一个简单的设计,比如 ...
随机推荐
- 【Spark】----Spark on Yarn
最近从Hadoop 1.x 转到Hadoop 2.x 同时将一些java 程序转为Scala的程序将平台上的代码减少了很多,在实施的过程中,开到一些Spark相关的YARN的部署上都是基于之前的Had ...
- 2016年5月11日摘自知乎的一些Redis大概了解
1. 知乎日报的基础数据和统计信息是用 Redis 存储的,这使得请求的平均响应时间能在 10ms 以下.其他数据仍然需要存放在另外的地方,其实完全用 Redis 也是可行的,主要的考量是内存占用.就 ...
- Python基础:元类
一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...
- ExtJs特点、优缺点及注意事项
摘自:ExtJs特点.优缺点及注意事项 1.什么是ExtJs?ExtJS可以用来开发RIA也即富客户端的AJAX应用,是一个用javascript写的,主要用于创建前端用户界面,是一个与后台技术无关的 ...
- Foreach能够循环的本质
我们对foreach循环并不陌生,在C#中我们用得非常多,但是我们是否清楚foreach循环的本质呢? 众所周知,foreach循环能够遍历 数组 ,集合 .但是我们自己定义的一个类是否能够通过fo ...
- csharp:Dapper Sample
You can find Dapper on Google Code here: http://code.google.com/p/dapper-dot-net/ and the GitHub dis ...
- LeetCode131:Palindrome Partitioning
题目: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...
- Verilog学习笔记设计和验证篇(一)...............总线和流水线
总线 总线是运算部件之间数据流通的公共通道.在硬线逻辑构成的运算电路中只要电路的规模允许可以比较自由的确定总线的位宽,从而大大的提高数据流通的速度.各个运算部件和数据寄存器组可以通过带有控制端的三态门 ...
- 多准则决策模型-TOPSIS方法
多准则决策–Multiple Criteria Decision Making 多准则决策–Multiple Criteria Decision Making 多准则决策是指在具有相互冲突.不可共度的 ...
- j2ee分布式缓存同步实现方案dlcache v1.0.0
现成的分布式K/V缓存已经有很多的实现,最主要的比如redis,memcached,couchbase.那为什么我们还要自己去实现呢,在我们解决了分布式系统下大量rpc调用导致的高延时后,我们发现很多 ...