4

拡張機能/プラグインをロードするためのサンドボックス化された AppDomain を作成しようとしています。アプリドメイン内でインスタンス化してdllをロードするMarshalByRefObjectがあります。dll を読み込もうとすると SecurityExceptions が発生しますが、サードパーティのコードが実行できることを制限しながら、それらを回避する方法がわかりません。私のプロジェクトはすべて.net 4です。

InDomainLoader クラスは完全に信頼されたドメインにあり、メソッドは SecuritySafeCritical とマークされています。私が読んだすべてから、これはうまくいくはずだと思います。

AppDomain を作成してそこにジャンプする Loader クラスを次に示します。

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 に設定されていて、 IsSecurityTransparentfalse であることを示しています。

これを簡単にするために、プロジェクト全体をhttp://davidhogue.com/files/PluginLoader.zipに圧縮しました。

誰かにアイデアがあれば、とても感謝しています。ここで行き止まりになっているようです。

4

1 に答える 1

6

まず、関数を SecuritySafeCritical としてマークするべきではありません。これは、信頼されていない呼び出し元があなたを呼び出す可能性があることを意味するためです。

あなたの問題に関しては、デフォルトではまだ特別なアクセス許可で実行されていないという問題があります。アセンブリのロードを行う通常の簡単な方法は、独自の AppDomainSetup を作成し、それが ApplicationBase を何らかの Plugin ディレクトリにポイントすることです (これは一般的には悪い考えではありません)、通常の Assembly.Load("AssemblyName") を使用してベースからロードできます。ただし、任意のファイルをロードする必要がある場合は、プラグイン dll (フル パス) の FileIOPermission をアサートする必要があります。

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

    return Assembly.LoadFile(file);
}
于 2010-09-13T23:53:58.733 に答える