如何从匿名委托或lambda访问安全关键字段?

时间:2012-12-19 16:12:46

标签: c# .net security .net-4.0 .net-4.5

方案

假设我们有下一个代码:

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

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

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

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

    问题

    你是如何克服这个的?

    简单的方法是实现标有critical的实际方法,而不是使用匿名委托。但这将我们带到了前匿名代表和lambas时代。 我不想要这个。

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

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

    实际上我认为安全透明度是一个很好的工具,因为它会强制更好,更安全的软件设计,关键操作非常本地化,其余代码以最小的权限工作。

1 个答案:

答案 0 :(得分: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]使局部变量和匿名方法(也许是匿名对象!)安全性安全至关重要。

是的! 我希望我的问题和我自己的答案对每个人都有用,因为我相信我的问题所描述的情况经常发生!