现在的位置: 首页 > 综合 > 正文

最近学习CAS的一点总结

2012年08月27日 ⁄ 综合 ⁄ 共 3712字 ⁄ 字号 评论关闭
 1 using System;
 2 using System.IO;
 3 using System.Security;
 4 using System.Security.Permissions;
 5 
 6 namespace Bee
 7 {
 8 [FileIOPermission(SecurityAction.Deny,Read=@"d:\")]
 9     class Test
10     {
11         static void Main(string []args)
12         {
13             Test test = new Test();
14             test.TestForCAS();
15         }
16         public void TestForCAS()
17         {
18             try
19             {
20                 FileIOPermission myPerm = 
21                     new FileIOPermission(FileIOPermissionAccess.Read,@"d:\");
22                 //myPerm.Demand(); 
23 
24                 if(File.Exists(@"d:\11.html"))
25                 {
26                     Console.WriteLine("Exsist!");
27                 }
28                 else
29                 {
30                     Console.WriteLine("Not Exsist!");
31                 }
32             }
33             catch(Exception ex)
34             {
35                 Console.WriteLine(ex.Message);
36             }
38         }
39     }
40 }

对于上面的结果:Not Exsist!(一切都基于用户机上有D:\11.html)
而我们将myPerm.Demand();的注释放开,得到一个安全异常。
若我们将myPerm.Demand();换成myPerm.Assert();得到结果是Exsist!
我们来分析这些现象的原因。
首先我们这个程序运行时,可以根据当前程序的Evidence可知
他具有Zone(mycompute),url(程序路径),hash(程序的hash)属性。
这时根据.net的默认的安全策略,这个程序拥有fulltrust的权限。(本人推荐 代码访问安全的实践 可以帮你更好的理解)。

首先我们来看.net框架中对bool File.Exists(string path)
函数的定义:

 1 public static bool Exists(string path)
 2 {
 3       try
 4       {
 5             if (path == null)
 6             {
 7                   return false;
 8             }
 9             if (path.Length == 0)
10             {
11                   return false;
12             }
13             path = Path.GetFullPathInternal(path);
14             new FileIOPermission(FileIOPermissionAccess.Read, new string[] { path }, false, false).Demand();
15             return File.InternalExists(path);
16       }
17       catch (ArgumentException)
18       {
19       }
20       catch (NotSupportedException)
21       {
22       }
23       catch (SecurityException)
24       {
25       }
26       catch (IOException)
27       {
28       }
29       catch (UnauthorizedAccessException)
30       {
31       }
32       return false;
33 }
34 
35 

上面标红的语句就是.net的CAS的具体实现方式。他在底层代码中重新调用Demand来检查当前代码的权限集,若无,就抛出安全异常。
至此,对于上述现象就可以解释了吧。
1。由于类具有[FileIOPermission(SecurityAction.Deny,Read=@"d:\")]属性,所以 if(File.Exists(@"d:\11.html"))返回false,但不抛异常。
2。这个就是很正常的一个表现了。对于
IPermission.Demand的实现,下面也将探讨一下
3。这个就是IPermission.Assert()的功能了。他能阻止CAS的定义的权限,但是无法阻止系统安全策略的权限。比如,根据系统安全策略
(包含企业,计算机,用户,应用程序域),当前程序只不具有访问C:的readFileIOPermission权限,你若用

1 FileIOPermission myPerm = 
2                     new FileIOPermission(FileIOPermissionAccess.Read,@"c:\");     
3                      
myPerm.Assert(); 
代码时,是无法获得c盘的访问权限的。具体原因也可在 代码访问安全的实践    找到。

我们再来看看FileIOPermission.Demand();的实现方法

 1 public void Demand()
 2 {
 3       CodeAccessSecurityEngine engine1 = SecurityManager.GetCodeAccessSecurityEngine();
 4       if ((engine1 != null&& !this.IsSubsetOf(null))
 5       {
 6             StackCrawlMark mark1 = StackCrawlMark.LookForMyCallersCaller;
 7             engine1.Check(thisref mark1);
 8       }
 9 }
10 
11 //这是CodeAccessSecurityEngine 的Check方法
12 
13 internal virtual void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
14 {
15       if (!this.PreCheck(cap, null1ref stackMark, PermissionType.DefaultFlag))
16       {
17             this.Check(PermissionToken.GetToken(cap), cap, ref stackMark, -1, (cap is IUnrestrictedPermission) ? 1 : 0);
18       }
19 }
20 
21 

还有具体很多代码,大伙可以具体研究,限于资料有限,也只能猜他的大概模型
(只针对CodeAccessSecurity),首先他有个跟代码栈有关的权限列表,程序栈最下面应该有个Fulltrust的权限,到了栈[FileIOPermission(SecurityAction.Deny,Read=@"d:\")]这里时权限就只有Fulltrust 去掉 FileIOPermission(FileIOPermissionAccess.Read,"d:\") 的权限。调起demand命令时,发现并无 FileIOPermission(FileIOPermissionAccess.Read,"d:\")权限,抛出异常。

抱歉!评论已关闭.