Вопрос

В этом коде я бы хотел, чтобы методу 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

Это было полезно?

Решение

Последующий Assert сводит на нет эффекты Deny.

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

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

[assembly:FileIOPermission(SecurityAction.RequestRefuse, Unrestricted=true)]

Другие советы

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

Однако, поскольку в .NET практически все необходимые требования Demands встроены, необходимость в самом деле Demand возникает редко, если только вы не выполняете Asserts (опять же, это редкость) или не написали свой собственный класс Permission.

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top