拡張機能/プラグインをロードするためのサンドボックス化された 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 に設定されていて、 IsSecurityTransparent
false であることを示しています。
これを簡単にするために、プロジェクト全体をhttp://davidhogue.com/files/PluginLoader.zipに圧縮しました。
誰かにアイデアがあれば、とても感謝しています。ここで行き止まりになっているようです。