Как отрицать Assert с CAS? - PullRequest
4 голосов
/ 03 марта 2009

В этом коде я бы хотел, чтобы метод ReadFileSystem был запрещен для утверждения разрешения на файловую систему.

Я ожидал, что это вызовет fileIo.Assert (), но это не так. Почему?

using System.Security.Permissions;
static void Main(string[] args)
{
    var fileIo = new FileIOPermission(PermissionState.Unrestricted);
    var secuPerm = new SecurityPermission(SecurityPermissionFlag.Assertion);
    PermissionSet set = new PermissionSet(PermissionState.Unrestricted);
    set.AddPermission(fileIo);
    set.AddPermission(secuPerm);
    set.Deny();
    ReadFileSystem();
    Console.Read();
}

private static void ReadFileSystem()
{
    var fileIo = newFileIOPermission(PermissionState.Unrestricted);
    fileIo.Assert();

    DirectoryInfo dir = new DirectoryInfo("C:/");
    dir.GetDirectories();
}

Обновление

Отличная ссылка здесь на CAS: http://blogs.msdn.com/shawnfa/archive/2004/08/25/220458.aspx

Ответы [ 3 ]

8 голосов
/ 08 марта 2009

Последующий Утверждение сводит на нет эффекты Отказа.

Способность утверждать FileIOPermission в основном зависит от того, является ли ваша сборка доверенной. На него не влияет предыдущий Deny of FileIOPermission. Оказывается, на него также не повлияло предыдущее отклонение Assertion SecurityPermission. Это потому, что SecurityPermissionFlag.Assertion проверяется как требование времени ссылки. Это не совсем задокументировано; Я нашел это здесь .

Чтобы заставить CLR не доверять вашей сборке для FileIOPermission, вы можете использовать следующее в верхней части файла, следуя инструкциям использования. Когда вы добавите это в свой файл, утверждение не вступит в силу. Это влияет на всю сборку. Нет более тонкой детализации.

[assembly:FileIOPermission(SecurityAction.RequestRefuse, Unrestricted=true)]
2 голосов
/ 08 марта 2009

Я думаю, что вы можете неправильно понять цель Утверждения разрешений. Когда вы утверждаете набор разрешений в CAS, вы фактически говорите: «Я знаю, что я делаю ... Мне все равно, какие разрешения находятся глубже в стеке». Это почти никогда , что вы хотите. Как правило, вы хотите требовать набор разрешений. Это приводит к обходу стека, в результате чего в стеке обнаруживается Deny, а затем возникает исключение безопасности.

Однако, поскольку в .NET встроены практически все необходимые требования, редко требуется фактически требовать что-либо, если вы не выполняете утверждения (опять же, это редко) или вы написали свой собственный класс Permission. 1005 *

1 голос
/ 08 марта 2009

Хороший вопрос наверняка. Я запустил код и тоже немного озадачен. Я просто провожу час или два, изучая документы и прибегая к помощи, но безрезультатно. Обратите внимание, что MSDN справляется, выполняя требование по утверждению.

Редактировать: ответ бинарного кодера указал мне правильное направление.

Права на Asserion просто не действительны в сборке с полным толчком. Только если вы добавите в начало файла следующее:

[assembly: SecurityPermissionAttribute(SecurityAction.RequestRefuse, Assertion = true)] 

вызов fileIo.Assert () не удастся.

Но в противном случае попытка отклонить () разрешение Assertion и следующий атрибут совершенно неэффективны (если вы явно не потребуете () права Assertion).

[SecurityPermissionAttribute(SecurityAction.Deny, Assertion = true)]
private static void ReadFileSystem() {}

В документации действительно говорится, что Assert () «имеет некоторые проблемы с безопасностью», и рекомендуется всегда требовать до утверждения:

fileIo.Demand();
fileIo.Assert();

но мне все еще нужно изменить свое мышление относительно применения принципа наименьших привилегий.

...