权限集最终就是一个有着零个或多个权限的集合。权限集通过System.Security.Permissionset名字空间以可编程方式公开。因为PermissionSet实现了System.Collections.ICollection接口,所以可以像处理标准集合那样处理权限集。集合中的元素保证至少要实现System.Security.IPermission接口。
IPermission接口是处理权限集的主要接口,它将针对类别(category)的操作模型化为权限设置。CLR提供了大约一打的内置类别,且每一个都支持Ipermission接口。对于一个特定类别的权限来说,可以有多个受保护的操作。IPermission接口提供了下列方法,以支持对权限对象设置操作:
namespace System.Security{
public <a href="http://www.lmwlove.com/ac/ID369" target="_blank" class="content_href" >interface</a > Ipermission{
Ipermission Union(Ipermission rhs);
Ipermission Intersect(Ipermission rhs);
bool IsSubsetof(Ipermission rhs);
Ipemission Copy();
void Demand();
}
}
前三个方法允许以集合方式处理相同类型的权限对象,如图9.5所示:
对Ipermission进行编程是相当直观的,例如,考虑下面的C#方法:
static void DoIt(){
SecurityPermissionFlag f1=SecurityPermissionFlag.Execution;
SecurityPermissionFlag f2=SecurityPermissionFlag.SkipVerification;
IPermission p1=new SecurityPermission(f1);
Ipermission p2=new SecurityPermission(f2);
//将p1的权限和p2的权限加到一起
Ipermission p3=p1.Union(p2);
//获得p1权限与p3权限的交集
Ipermission p4=p3.Intersect(p1);
Debug.Assert(p4.IsSubsetOf(p3));
Debug.Assert(p1.IsSubsetOf(p3));
}
在这个示例中,SecurityPermission类型支持一个标明允许哪些操作的位掩码(bitmask)。对Union方法的调用会返回一个新的SecurityPermission对象,它既具有Execction位集,也具有SkipVerification位集(好像执行了位操作OR一样)。在这个示例中,当调用Intersect方法时,结果得到的新的SecurityPermission对象只有Execution位集(好像执行了位操作AND一样)。IsSubseof方法只是测试p1支持的每一个操作p3是不是也支持,它可以通过将pl的位掩码同pl和p3的交集结果进行比较计算而得到。
IPermission的方法假定提供的权限类型相同。例如,将FileIOPermission对象传人WebPermission对象的Intersect方法将会出错,大多数权限类型支持使用位掩码来指明启用哪些操作的同时,许多权限类型还携带了附加信息,例如,文件路径或主机名。这种类型相关的信息取决于IPermission的方法的实现方式。例如,考虑下面使用FileIOPermission类型的示例:
static void DoIt(){
FileIOPermissionAccess all=FileIOPermission|Access.AllAccess;
IPermission p1=new FileIOPermission(all,@”c:\etc”);
IPermission p2=new FileIOPermission(all,@”c:\etc\bin”);
IPermission p3=p1.Union(p2); //C:\etc被允许
Ipermission p4=p1.Intersect(p2) ; //C:\etc\bin被允许
Debug.Assert(p2.IsSubsetOf(p1)) ;
Debug.Assert(p1.IsSubsetOf(p2)==false);
}
Union,Intersect和IsSubsetOf的精确语义是类型相关的,详情请参考特定权限类型的文档。
一般说来,权限类型支持一个接收System.Security.Permission.PermissionState枚举的构造器,以允许将新的权限对象设置为一个众所周知的状态。PermissionState枚举很简单:
namespace System.Security.Permissions{
public enum PermissionState{
None;
Unerstricted
}
}
以PermissionState.None初始化的权限对象,表示将该类型设置为限制最严的极限集合。PermissionState.Unrestricted表示为该类型设置限制最松的权限集合。此外,为了使权限对象能被常规地检查其最低限制状态,支持无限制访问的权限类型,还必须支待System.Security.
PermisSions.IUnrestrictedPermission接口:
namespace System.Security.Permissions{
public <a href="http://www.lmwlove.com/ac/ID369" target="_blank" class="content_href" >interface</a > IunrestrictedPermission{
bool IsUnrestricted();
}
}
支持这个接口的权限类型,表明它们支持无限制权限的概念,这就隐式地授予了该权限类型所有可能的权限。当一个权限对象被授予无限制的权限时,该权限对象类型里所有可能的操作就都被隐式地允许。
PernissionState和IUnrestrictedPermission允许以一致的方式处理权限对象,而不管无限制的访问细节到底是怎么指定的,从而允许下面一般性的代码对于所有权限类型T始终保持为true:
IunrestrictedPermission perm=new T(PermissionState.Unrestricted);
Debug.Assert(perm.IsUnrestricted());
不过要知道,即使它不是以那种方式显式地初始化,一个权限对象也可能是无限制的、例如, 传递securityPermissionFlag.AllAess参数到SecurityPemission的构造器,等价于传递PermissionState.Unrestricted。此外,对权限对象执行并集操作,结果也可能会产生一个无限制的权限对象。
通过实现IPermission接口,以及与它关系密切的接口(它们可以用于将权限对象编码到XML中)你可以定义自己的权艰类型。同时,CLR还提供了一个家族系列的内置权限类型,用于保护各种系统级资源。表9.2列出了最常使用的权限类型。可以看到,除了标识权限(identity permission)外,其他权限类型都支持IUnrestrictedPermission接口。还有许多权限类型允许基于模式匹配来设置权限,对于保护像文件系统和网络资源这样基于位置的资源权限来说,这才具有真正的意义。
t