我正在尝试创建一个沙盒AppDomain来加载扩展/插件。我有一个在appdomain中实例化的MarshalByRefObject来加载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为true,方法的IsSecurityCritical和IsSecuritySafeCritical都设置为true,而IsSecurityTransparent为false。
我将整个项目压缩到http://davidhogue.com/files/PluginLoader.zip中,以防这会让这变得更容易。
如果有人有任何想法,我将不胜感激。我好像被困在了死胡同里。
发布于 2010-09-14 07:53:59
首先,您可能不应该将函数标记为SecuritySafeCritical,因为这意味着不受信任的调用者可以调用您,这可能不是您真正想要的(并不是说这应该是一个主要问题)。
至于你的问题,问题是在默认情况下,你仍然没有任何特殊的权限运行,正常的简单方法是你创建自己的AppDomainSetup,并将它的ApplicationBase指向某种插件目录(通常这不是一个坏主意),然后你可以使用普通的Assembly.Load("AssemblyName")从库中加载。但是,如果您必须加载任意文件,则需要为插件dll断言FileIOPermission (完整路径),即
private Assembly LoadAssemblyFromFile(string file)
{
FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, file);
perm.Assert();
return Assembly.LoadFile(file);
}https://stackoverflow.com/questions/3704981
复制相似问题