我想创建一个沙箱AppDomain加载扩展/插件。我有一个MarshalByRefObject,它在appdomain内部实例化以加载dll。我在尝试加载dll时遇到了SecurityExceptions,我无法弄清楚如何绕过它们,同时还限制了第三方代码可以执行的操作。我的所有项目都是.net 4.C#完全信任的程序集与SecuritySafeCritical功能仍然抛出SecurityExceptions
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
为真,且该方法将IsSecurityCritical
和IsSecuritySafeCritical
设置为true,IsSecurityTransparent
为false。
我将整个项目压缩到http://davidhogue.com/files/PluginLoader.zip以防万一,这样做更容易。
如果有人有任何想法,我会非常感激。我似乎在这里陷入死胡同。
好吧,我会试试看。我认为这会让我解决当前的问题。虽然,我的集会不应该完全信任,因此能够做几乎任何想要的事情? – 2010-09-14 05:31:23
它是完全可信的,就在你得到安全异常的时候_thread_(对于任何更好的定义)不是。完全信任允许您声明正确的权限,如果该函数在部分信任程序集中,那么它将不被允许,除非它明确位于授权集中。 – tyranid 2010-09-14 05:45:33