C # полностью доверенная сборка с функцией SecuritySafeCritical, по-прежнему генерирующая исключения SecurityException - PullRequest
4 голосов
/ 14 сентября 2010

Я пытаюсь создать изолированную AppDomain для загрузки расширений / плагинов.У меня есть MarshalByRefObject, который в экземпляре внутри appdomain для загрузки DLL.Я получаю SecurityExceptions при попытке загрузить dll, и я не могу понять, как их обойти, все еще ограничивая возможности стороннего кода.Все мои проекты .net 4.

Класс InDomainLoader находится в полностью доверенном домене, метод помечен как SecuritySafeCritical.Из всего, что я прочитал, я думаю, что это должно работать.

Вот мой класс Loader, который создает AppDomain и переходит в него:

public class Loader
{
    public void Load(string dll, string typeName)
    {
        Log.PrintSecurity();

        // Create new AppDomain
        var setup = AppDomain.CurrentDomain.SetupInformation;
        var permissions = new PermissionSet(null);
        permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        var strongname = typeof(InDomainLoader).Assembly.Evidence.GetHostEvidence<StrongName>();
        var strongname2 = typeof(IPlugin).Assembly.Evidence.GetHostEvidence<StrongName>();
        AppDomain domain = AppDomain.CreateDomain("plugin", null, setup, permissions, strongname, strongname2);

        // Create instance
        var loader = (InDomainLoader)domain.CreateInstanceAndUnwrap(
            typeof (InDomainLoader).Assembly.FullName, typeof (InDomainLoader).FullName);

        // Jump into domain
        loader.Load(dll, typeName);
    }
}

А вот загрузчик начальной загрузки, который запускается вдомен:

public class InDomainLoader : MarshalByRefObject
{
    [SecuritySafeCritical]
    public void Load(string dll, string typeName)
    {
        Log.PrintSecurity();

        var assembly = Assembly.LoadFrom(dll);  // <!-- SecurityException!
        var pluginType = assembly.GetType(typeName);

        var demoRepository = new DemoRepository();
        var plugin = (IPlugin)Activator.CreateInstance(pluginType, demoRepository);
        Console.WriteLine(plugin.Run());
    }
}

Некоторые операторы журналирования говорят мне, что IsFullyTrusted сборки имеет значение true, а для метода IsSecurityCritical и IsSecuritySafeCritical установлено значение true, IsSecurityTransparent равно false.

Я сжал весь проект до http://davidhogue.com/files/PluginLoader.zip на случай, если это облегчит эту задачу.

Если у кого-то есть какие-либо идеи, я был бы очень благодарен.Кажется, я застрял здесь в тупике.

1 Ответ

6 голосов
/ 14 сентября 2010

Ну, для начала вы, вероятно, не должны отмечать функцию как SecuritySafeCritical, поскольку это подразумевает, что ненадежные абоненты могут вызывать вас, чего вы, вероятно, не очень хотите (не то, чтобы это было серьезной проблемой).

Что касается вашей проблемы, то проблема в том, что по умолчанию вы все еще не запускаете с какими-либо специальными разрешениями, нормальный простой способ сделать загрузку сборки - это создать свой собственный AppDomainSetup и указать его ApplicationBase на некоторый каталог Plugin. (что, в общем-то, неплохая идея), вы можете использовать обычный Assembly.Load ("AssemblyName") для загрузки из базы. Однако, если вам необходимо загрузить произвольный файл, вам нужно установить FileIOPermission для плагина dll (полный путь), т.е.

private Assembly LoadAssemblyFromFile(string file)
{
    FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, file);
    perm.Assert();

    return Assembly.LoadFile(file);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...