【文章标题】: 代码访问安全性01
【文章作者】: 有酒醉
【作者邮箱】: wuqr32@sina.com
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
一、代码访问安全性概念
代码访问的目的是阻止用户编写那些他们希望执行,但是又不能绝对确信的代码.实现安全性可以根据用户身份和您对代码的信任度来限制对资源的访问.如果使用代码访问安全性,在只有运行进程的帐号被允许访问资源,并且包含相关代码的程序集也被允许访问该资源的情况下,系统才允许该程序集访问该资源.
基于帐号身份的安全是Windows安全性能和CLR的角色安全性能所提供.
1、针对单个程序集的CAS
非托管代码中的特权和权限的差别是:特权与一个帐号相关联,并且指出一个帐号可以执行的操作;而权限则与特殊的资源相关联.CAS中与Windows用户组等效的概念是代码组,代码组将赋予了相同权限集的程序集组合在一起.Windows中可以将用户放入用户组中以便管理,而CAS的代码则通过证据来确认一个程序集是否属于某个代码组(因为将所有程序集放入代码组中是很不现实的:每新建一个项目都有多个新的程序集).
检查该程序集属于某个代码组的一些特征:
签名 -- 是否已给一个程序集分配了一个特殊的强名称、凭证或者它的散列值是否等同于一个特定的值.
位置 -- 程序集的位置(本地或是下载它的URL或WEB站点)
区域 -- 本地计算机,企业内部网,信任域中的Internet站点,不信任域中的Internet站点,其他站点
自定义条件 -- 编写实现自己的成员资格条件,并将这些代码插入到安全基础结构中
代码组和相关的代码资格条件的集合构成了CLR的安全策略部分.每次加载执行程序集中的代码时,CLR都会在后台检查该程序集所属的代码组,并确保默认的安全策略允许该程序集执行它试图执行的任务.而一旦确定了程序集所属的代码组,就需要找出代码所具有的权限(也可以是自定义的权限).
[图mscorcfg.msc:代码组和权限集]
2、针对多个程序集的CAS
在多个程序集引用的过程中,允许代码所执行的操作问题不仅取决于它自己的程序集,而且还取决于调用堆栈上所有程序集合的标识.通过堆栈移动检查堆栈上的所有程序集的权限集.
Demand(需求) -- 如果调用堆栈上有一个程序集不具有权限(所需求的),那么安全检查就会失败
Assert(确认) -- 允许某些代码在没有某个权限的情况下,通过中间程序集来确认这个权限,从而达到目的
Deny(拒绝) -- 通知CLR不能为当前正在运行的方法直接或间接激活的其他任何方法授予它们所请求的权限
PermitOnly(只允许) -- 只允许针对已明确指定的权限的请求,而不允许对其他所有权限的请求
3、CLR权限
CLR权限的完整列表(详细信息参阅MSDN)
+--------------------------+---------------------+-----------------------+-----------------+
+ Directory Services + DNS + Environment Variables + Event Log +
+--------------------------+---------------------+-----------------------+-----------------+
+ File Dialog + File IO + Isolated Storage File + Message Queue +
+--------------------------+---------------------+-----------------------+-----------------+
+ OLE DB + Performance Counter + Printing + Reflection +
+--------------------------+---------------------+-----------------------+-----------------+
+ Registry + Security + Service Controller + Socket Access +
+--------------------------+---------------------+-----------------------+-----------------+
+ SQL Client + User Interface + Web Access + +
+--------------------------+---------------------+-----------------------+-----------------+
这些权限涉及了许多架构类库中的各种类启用的一系列可能很危险的操作.并且,相关类使用这些权限来限制可以这些操作的代码.
示例1 - 查阅FileInfo类读取文件的内在机制
cmd >ildasm mscorlib.dll
查阅FileInfo构造函数(节选):
...
IL_0007: brtrue.s IL_0014
IL_0009: ldstr "fileName"
IL_000e: newobj instance void System.ArgumentNullException::.ctor(string)
IL_0013: throw
IL_0014: ldarg.0
IL_0015: ldarg.1
IL_0016: stfld string System.IO.FileSystemInfo::OriginalPath
IL_001b: ldarg.1
IL_001c: call string System.IO.Path::GetFullPathInternal(string)
IL_0021: stloc.0
IL_0022: ldc.i4.1
IL_0023: ldc.i4.1
IL_0024: newarr System.String
IL_0029: stloc.1
IL_002a: ldloc.1
IL_002b: ldc.i4.0
IL_002c: ldloc.0
IL_002d: stelem.ref
IL_002e: ldloc.1
IL_002f: ldc.i4.0
IL_0030: ldc.i4.0
IL_0031: newobj instance void System.Security.Permissions.FileIOPermission::.ctor(valuetype System.Security.Permissions.FileIOPermissionAccess,
string[],
bool,
bool)
IL_0036: call instance void System.Security.CodeAccessPermission::Demand()
IL_003b: ldarg.0
IL_003c: ldarg.1
IL_003d: call string System.IO.Path::GetFileName(string)
IL_0042: stfld string System.IO.FileInfo::_name
...
翻译为C#代码:
public FileInfo(string fileName)
{
if (fileName == null)
{
throw new ArgumentNullException("fileName");
}
base.OriginalPath = fileName;
string text1 = Path.GetFullPathInternal(fileName);
new FileIOPermission(FileIOPermissionAccess.Read, new string[] { text1 }, false, false).Demand();
this._name = Path.GetFileName(fileName);
base.FullPath = text1;
}
换句话说,用FileInfo对象读文件将需要FileIOPermission权限,CLR代码主动需求安全性.
<续>
--------------------------------------------------------------------------------
【版权声明】: 本文原创于泉州软件基地, 转载请注明作者并保持文章的完整, 谢谢!
2007年03月30日 18:14:15