我正在尝试创建一个沙盒 AppDomain 来加载扩展/插件。我有一个 MarshalByRefObject,它在 appdomain 内实例化以加载 dll。我在尝试加载 dll 时遇到 SecurityExceptions,我不知道如何绕过它们,同时仍然限制第三方代码可以做什么。我所有的项目都是.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
是真的,并且该方法具有两者IsSecurityCritical
并IsSecuritySafeCritical
设置为真,IsSecurityTransparent
是假的。
我将整个项目压缩到http://davidhogue.com/files/PluginLoader.zip,以防万一这更容易。
如果有人有任何想法,我将不胜感激。我似乎在这里陷入了死胡同。