.Net中的安全机制

这部分内容由于工作中接触的不多,所以理解起来用了不少时间,下面只是作简单的说明:

     Windows中的安全机制主要是这几个概念:我是谁(身份)、我要做什么(操作)、我要访问什么(资源)。而.Net中将其修改为我从哪里来(位置)、我要做什么(操作)、我要访问什么(资源)。由此.Net的安全机制中有这几个概念:代码组、程序集、权限、权限集。

     代码组是对程序集在安全方面的一个分类,它是一个树状结构,程序集可以属于代码组中的某个节点。这个隶属关系不需要用户去指定,每个代码有且仅有一个代表自身的条件,如zone、site、strong name、url等,程序集自动的会属于代码树状结构中的一条分支。下面是典型的本机代码组的设置:

     image

     我们就可以看几个例子,如:本机上的一个程序集,自然会属于代码组1.1. Zone - MyComputer(这个代码组的条件就是zone为本机);而我们从某台服务器的共享目录中访问的程序集就会属于1.3. Zone - Internet。当然如果有其他更细条件的代码组,而程序集也符合这样的条件,他就会隶属于更明细的代码组。

     权限在.Net Framework中的体现就是自带的权限类,.Net Framework中实现了很多权限实例类,如FileIOPermission、UIPermission、FileDialogPermission(都继承自CodeAccessPermission),每个权限实体类还定义了对此权限的操作,如FileIOPermission中有Read、Write等。

     权限集,顾名思义就是权限的集合,定义这个集合是为了方便给代码组分配权限,一个代码组对应着一个权限集。这个权限集使用xml来表示,明确表达了这个集合所拥有的权限。下面是名为Internet的权限集的详细描述:

     image

     可以看到每一条都代表着一个权限,也明确对应着一个权限实体类,在运行时这个xml会被反射成权限对象以供使用。

     下图就是安全机制中元素的关系图:

     image

     一个程序集隶属于某个代码组,而代码组被分配了一个权限集,这样一个程序集就知道了自己在运行时所拥有的权限的集合。当程序集中的代码在运行时进行某个操作时,.Net Framework就会去检查这个程序集所拥有的权限,如果没有权限则抛出SecurityException,下面就是创建StreamReader实例时的调用堆栈,从中可以看到.Net Framework进行了权限检查。

at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
at System.IO.StreamReader..ctor(String path)

     而对于自己编写的权限,就可以在自己的代码中做类似的检查。

     还可以更细的定义程序集的权限,现在的程序集的权限主要是根据其所属的代码组,程序集本身也可以拥有自身的权限定义。如:要求一个必须的权限,如果代码组中没有此权限,则程序不能启动;如可以否定某个权限,则即使在代码组中有此权限,程序集以及其调用的其他程序集也没有这个权限。程序集权限可以在Security选项卡中指定,也可以在代码中通过代码或者是特性来指定。

     还有值得注意的,对权限的检查不光是对本程序集的权限检查,还包括对调用堆栈上的较高的位置的程序集权限的检查。像这样的场景:有一个服务器端的组件可以操作本机的某个Windows Service,这个组件在服务器本机上有Full Trust的权限集合,因此从服务器端启动它来访问某个Windows Service是没有问题的。但如果想从客户端通过WebService来调用此组件,则是不行的,因为权限检查在调用堆栈中从这个组件开始一直检查到这个调用的起始处,发现这个程序集来自Internet,因此就使用Internet权限组,而这个权限组没有操作Windows Service的权限。要使这个调用成功,就需要改服务器上的代码组权限,最好的是新增一个条件比较明确的代码组,否则就将带来安全问题。

posted on 2008-10-15 17:12  栖息的熊  阅读(701)  评论(1编辑  收藏  举报

导航