CAS 代码访问安全性二 (翻译)

试一下下面的代码,我们之前没有使用security命名空间,但是我们现在来用用看。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> using  System.Security;
using  System.Security.Permissions;

添加另一个button到已经存在的form上。


<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private   void  btnFileRead_Click( object  sender, System.EventArgs e)
{
    
try
    {
        InitUI(
1 ); 
    }
    
catch  (SecurityException err)
    {
        MessageBox.Show(err.Message,
" Security Error " );
    }
    
catch  (Exception err)
    {
        MessageBox.Show(err.Message,
" Error " );
    } 
}

InitUI只是调用ShowUI函数。记住它已经被拒绝了对c盘的读操作。


<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> //  Access is denied for this function to read from C: drive
//  Note: Using declrative syntax
[FileIOPermission(SecurityAction.Deny,Read = " C:\\ " )]
private   void  InitUI( int  uino)
{
    
//  Do some initializations
    ShowUI(uino);     //  call ShowUI
}

ShowUI函数得到uino显示适当的UI


<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private   void  ShowUI( int  uino)
{
    
switch  (uino)
    {
        
case   1 //  That's our FileRead UI
            ShowFileReadUI();
            
break ;
        
case   2 :
            
//  Show someother UI
             break ;            
    }
}

ShowFileReadUI显示与读文件有关的UI

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private   void  ShowFileReadUI()
{
    MessageBox.Show(
" Before calling demand " );
    FileIOPermission myPerm 
=   new  
      FileIOPermission(FileIOPermissionAccess.Read, 
" C:\\ " );
    myPerm.Demand();
       
//  All callers must have read permission to C: drive
      
//  Note: Using imperative syntax
      
    
//  code to show UI
    MessageBox.Show( " Showing FileRead UI " );
    
//  This is excuted if only the Demand is successful.
}

我知道这是一个槽糕的例子,但是它已经足够了。

现在运行我们的代码。你会得到一个“Before calling demand”的消息,然后跳出一个自定义的错误对话框“security error”。哪里错了呢?看下面的图片:


【图11

我们已经禁止了InitUI方法的读的权限。所以当ShowFileReadUI请求对c盘的写的权限的时候,它检查堆栈的时候找到不是每个调用者都被允许这个demanded permission,显示一个异常。只需要注释在InitUI方法里面注释Deny statement, 它就可以工作了,因为所有的调用者都有demandedpermission

 

注意,根据文档,许多.NET Framework的类已经有了demands关联它。例如StreamReaderStreamReader自动需要FileIOPermission.所以用其他demand去替换它会导致一个堆栈的错误。

Link Demand

一个link demand只检查你的代码的直接调用者。那意味者它不会对堆栈起作用。当你的代码跳到一个典型的引用,包括函数指针引用和方法调用会发生link。一个link demand只能用申明的方式。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> [FileIOPermission(SecurityAction.LinkDemand,Read = " C:\\ " )]
private   void  MyMethod()
{
    
//  Do Something 
}

Inheritance Demand

Inheritance Demand能过被类和方法应用。如果它用到一个类上,所有从它继承的类都具有它的permission

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> [SecurityPermission(SecurityAction.InheritanceDemand)]
private   class  MyClass()
{
    
//  what ever
}

如果它用到一个方法上,所有继承它的类必须制定permission去重写那个方法。


<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> private   class  MyClass()
{
    
public   class  MyClass() {}
    
    [SecurityPermission(SecurityAction.InheritanceDemand)]
    
public   virtual   void  MyMethod()
    {
        
//  Do something
    }
}

就像link demandinheritance demand也只能用声明的方式。

Requesting Permissions

想象一个场景。你给一个用户一个form其中包含有20多个field去填充,所有的信息必须保存在一个text文件中,用户填充了所有的信息,当他要保存的时候,他得到了一个信息,他没有足够的权限去创建一个文件。当然你可以试图沉静的告诉他为什么会发生这个,因为我们调用堆栈的时候...因为一个demand。。如果你足够幸运,你可以从microsoft那得到这个警示(相信我...有时他确实会发生)。

 

你在装载装配的时候请求permission的优先级是否比较容易呢?这里有3种方法去做他在CAS中。

  • RequestMinimum

  • RequestOptional

  • RequestRefuse

注意这些只能用声明的语法应用在装配的级别,而不是应用给方法或者是类。最棒的是管理员可以在装配之后查看请求的permissions,使用permview.exe你可以查看它所被赋予的permissions

RequestMinimum

你可以使用requestMinimum去指定permissions。代码只允许在所有permissions都被赋予的时候才能够跑。在下面的代码片段中,有一个请求去写注册表的请求。如果这个没有被安全机制赋予权限,这个装配甚至不会被装载。就像之前提到的,这种请求能够在装载的时候完成。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> using  System;
using  System.Windows.Forms;
using  System.IO;

using  System.Security;
using  System.Security.Permissions;

//  placed in assembly level
//  using declarative syntax
[assembly:RegistryPermission(SecurityAction.RequestMinimum, 
         Write
= " HKEY_LOCAL_MACHINE\\Software " )]

namespace  SecurityApp
{
    
//  Rest of the implementation
}

RequestOptional

使用RequestOptional,你能指定你的代码所需要的permissions,而不是跑的时候才请求。如果你的代码没有被赋予optional permissions,你必须处理代码片段在执行时需要optional permissions而抛出的异常。这里有一些在使用requestOptional时必须注意的事情

如果你使用RequestOptionalRequestMinimum,除了他们两再没有其他的permissions将被赋予,如果被安全机制所允许。尽管安全机制允许添加permissions到你的装配集,他们将不会被赋予。看下面的代码片段:

[assembly:FileIOPermission(SecurityAction.RequestMinimum, Read="C:\\")]

[assembly:FileIOPermission(SecurityAction.RequestOptional, Write="C:\\")]

这个装配集的permissions只是对文件系统的读和写。是否还需要显示UI?然后这个装配集被装载,但是一个异常被抛出,当显示UI的代码被执行的时候,因为尽管安全机制允许UIPermission,但是它没有被装配集允许。

RequestRefuse

你可以使用RequestRefuse去指定你确定不需要被赋予的permissions在你的代码中,即使他们已经被安全机制赋予了,然后拒绝写的permission将保证你的代码不会被滥用

[assembly:FileIOPermission(SecurityAction.RequestRefuse, Write="C:\\")]






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值