Утверждать разрешения в C # - PullRequest
7 голосов
/ 05 февраля 2012

Я занят, пытаясь понять, что такое безопасность в c #, и я изо всех сил пытаюсь понять, как работает Assert.Я использую .net 3.5.

Я сделал пример приложения, чтобы попытаться понять это.

Вызов метода:

[FileIOPermission(SecurityAction.Deny, ViewAndModify = @"C:\")]
    static void Main(string[] args)
    {
        WriteTest testWriter = new WriteTest();
        testWriter.Test();
        Console.Read();
    }

В отдельной библиотеке классов у меня есть:

public class WriteTest
{
    public void Test()
    {
        try
        {
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, @"C:\");
            permission.Assert();
            using (StreamWriter sw = new StreamWriter(@"C:\test.txt"))
            {
                sw.WriteLine("testing!");
                sw.Flush();
            }
            Console.WriteLine("Writen to file!");
        }
        catch (SecurityException sec)
        {
            Console.WriteLine("No privileges!");
        }
    }
}

Этот код выполняется нормально и все.Он напишет в файл.У меня вопрос, как именно это работает?Разве это не делает недействительными классы безопасности, если я могу просто утверждать нужные мне разрешения, чтобы пропустить проверки?Если я изменяю Assert на Demand, это вызывает исключение.

Разве классы безопасности не позволяют мне устанавливать разрешения так, чтобы, когда я вызываю сторонний класс, я мог предотвратить его мошенничество и делать вещи, которые я не хочу делать?Я знаю, если я загружу dll в AppDomain, я получу этот эффект, даже если сторонняя DLL-библиотека действительно использует Assert, просто странно, что, если я вызываю ее напрямую, она будет работать.Я пытался прочитать документацию MSDN об Assert, но мне трудно понять.

Ответы [ 2 ]

3 голосов
/ 05 февраля 2012

Assert() полезно, когда less -привилегированный код («Сборка A») вызывает more -привилегированный код («Сборка B») для выполнения некоторой задачи. Чтобы выполнить эту задачу, сборка B должна запустить код, который требует мощного разрешения - разрешения, которого сборка A может не иметь. Таким образом, сборка B сначала требует менее мощного разрешения (прежде всего разрешения на выполнение задачи), а затем утверждает более мощное разрешение для фактического выполнения задачи.

Например, предположим, что приложение Silverlight с частичным доверием хочет сделать HTTP-запрос, используя класс System.Net.WebRequest. Для установки сетевого соединения требуется SocketPermission, но это мощное низкоуровневое разрешение, которое не следует предоставлять ненадежному коду из Интернета. Таким образом, WebRequest требует менее мощного разрешения WebPermission, а затем подтверждает SocketPermission перед продолжением установки сетевого подключения.

Теперь, в вашем конкретном примере, Assert() переопределяет Deny, потому что библиотека классов работает с тем же уровнем привилегий , что и приложение - и приложение, и библиотека классов, вероятно, работают как Полное доверие. Сборка всегда может Assert() иметь любое разрешение в своем наборе разрешений. Чтобы применить Deny к библиотеке классов, вам нужно будет поместить библиотеку классов в песочницу.

Примечание: В .NET 4.0, Deny устарело. От MSDN Library :

Поддержка времени выполнения удалена для обеспечения выполнения запросов разрешений Deny, RequestMinimum, RequestOptional и RequestRefuse. В целом, эти запросы не были хорошо поняты и представляли потенциальную уязвимость безопасности, когда они не использовались должным образом:

  • Действие Deny может быть легко отменено действием Assert. Код в сборке смог выполнить действие Assert для разрешения, если разрешение было в праве, установленном для сборки. Assert предотвратил отображение Deny в стеке, что сделало его неэффективным.
1 голос
/ 05 февраля 2012

Метод Assert() заставляет Code Access Security (CAS) прекратить обход стека по конкретному запросу проверки прав доступа.

Assert - это метод, который можно вызывать при разрешении доступа к коду. классы и класс PermissionSet. Вы можете использовать Assert, чтобы включить ваш код (и вызывающие абоненты) для выполнения действий, которые ваш код имеет разрешение на выполнение, но его вызывающие могут не иметь разрешения на выполнение. Утверждение безопасности изменяет нормальный процесс, который среда выполнения выполняет во время проверки безопасности. Когда вы утверждаете разрешение, это говорит системе безопасности не проверять абонентов вашего кода на заявленное разрешение.

Использование метода подтверждения

Я думаю, что вы хотите Demand()

Интереса:

...