19

设想

假设我们有下一个代码:

[SecuritySafeCritical]
public void SomeMethod()
{
    SomeCriticalClass critical = new SomeCriticalClass();

    Action someDelegate = () => 
    {
         critical.Do();
    }

    someDelegate();
}
  1. SomeMethod签名具有[SecuritySafeCritical]属性。
  2. SomeCriticalClass[SecurityCritical]是在类或方法方法级别具有属性的某个类Do
  3. 我们创建了一个匿名委托,自动推断为Action.

问题

调用critical.Do()会导致 a ,因为安全透明方法(匿名方法)正在尝试访问安全关键字段(SomeCriticalClass 局部变量)。MethodAccessException FieldAccessExceptioncritical

问题

你是如何克服这一点的?

简单的方法是实现一个标记为的实际方法,[SecuritySafeCritical]而不是使用匿名委托。但这使我们进入了匿名代表和lambas时代。我不想要这个。

其他简单的方法就是不使用安全透明性这不是解决方案。

几乎所有来自 Microsoft 和开源社区的可用库在设计时都没有考虑到安全透明性。[SecuritySafeCritical]也就是说,任何自己的自定义代码都必须通过方法[SecurityCritical]/属性/委托与第三方库进行互操作。

实际上,我相信安全透明性是一个很好的工具,因为它可以强制进行更好和安全的软件设计,关键操作非常本地化,并且其余代码以最少的权限工作。

4

1 回答 1

18

抱歉,我等不及其他回答者了……我找到了解决方案!

通过实验,我可以确定使用[SecuritySafeCritical]具有在其主体中创建匿名方法的方法的类进行标记,可以解决问题!

换句话说,或谈论代码

[SecurityCritical]
public class SomeCriticalClass
{
      [SecurityCritical]
      public void Do()
      {
      }
}

[SecuritySafeCritical]
public sealed class SomeClass
{
    [SecuritySafeCritical]
    public void SomeMethod()
    {
          SomeCriticalClass critical = new SomeCriticalClass()

          // No more FieldAccessException!
          Action action = () => critical.Do();         
    }
}

我想澄清一下:

  • SomeClass用标记类[SecuritySafeCritical]并不意味着所有声明的方法都将[SecuritySafeCritical]默认为。这意味着该类可以被部分信任的调用者使用。您仍然需要用[SecuritySafeCritical]属性标记那些可以被部分信任的调用者访问的方法、属性或字段。

  • 似乎[SecuritySafeCritical]在类级别使局部变量和匿名方法(也可能是匿名对象!)安全至关重要。

是的! 我希望我的问题和我自己的回答都对大家有用,因为我相信我的问题中描述的情况会经常发生!

于 2012-12-19T17:20:20.080 回答