Как получить доступ к критическому полю безопасности от анонимного делегата или лямбда? - программирование
Подтвердить что ты не робот

Как получить доступ к критическому полю безопасности от анонимного делегата или лямбда?

Сценарий

Скажем, у нас есть следующий код:

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

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

    someDelegate();
}
  • Подписи SomeMethod имеет атрибут [SecuritySafeCritical].
  • SomeCriticalClass - это некоторый класс, который имеет атрибут [SecurityCritical] либо на уровне метода, либо на методе Do.
  • Мы создаем анонимный делегат, автоматически определяемый Action.

Проблема

Вызов critical.Do() вызывает MethodAccessException FieldAccessException, потому что прозрачный метод безопасности (анонимный метод) пытается получить доступ к критическому значению безопасности (локальная переменная critical SomeCriticalClass).

Вопрос

Как вы преодолеваете это?

Простым способом будет использование фактического метода, помеченного [SecuritySafeCritical] вместо использования анонимного делегата. Но это приводит нас к анонимным делегатам и эры lambas. Я не хочу этого.

Другим простым способом было бы просто не использовать прозрачность безопасности. Это не решение.

Почти все доступные библиотеки как из Microsoft, так и из сообщества с открытым исходным кодом не разработаны с учетом прозрачности безопасности. То есть любой собственный код должен взаимодействовать с сторонними библиотеками через [SecuritySafeCritical] или [SecurityCritical] методы/свойства/делегаты.

На самом деле я считаю, что прозрачность безопасности - хороший инструмент, потому что он создает лучшие и безопасные разработки программного обеспечения, критические действия очень локализованы, а остальная часть кода работает с минимальными разрешениями.

4b9b3361

Ответ 1

Извините, но я не мог дождаться других ответчиков... Я получил решение!

В результате экспериментов я мог определить, что маркировка с [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] на уровне класса создает локальные переменные и анонимные методы (возможно, анонимные объекты тоже!) безопасно безопасно.

Да! Я надеюсь, что и мой вопрос, и мой собственный ответ будут полезны для всех, потому что я считаю, что ситуация, описанная в моем вопросе, может часто случаться!