目标:我需要在权限非常有限的AppDomain中运行一些代码 - 它应该无法访问任何花哨或不安全的内容,除了之外我在其他地方定义的辅助方法。
我做了什么:我正在创建一个具有所需基本权限的沙箱AppDomain,并创建一个运行代码的代理对象:
static AppDomain CreateSandbox()
{
var e = new Evidence();
e.AddHostEvidence(new Zone(SecurityZone.Internet));
var ps = SecurityManager.GetStandardSandbox(e);
var security = new SecurityPermission(SecurityPermissionFlag.Execution);
ps.AddPermission(security);
var setup = new AppDomainSetup {
ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
};
return AppDomain.CreateDomain("Sandbox" + DateTime.Now, null, setup, ps);
}
public class Proxy : MarshalByRefObject
{
public Proxy() { }
public DoStuff()
{
// perform custom operation requiring permission
HelperAssembly.HelperMethods.Method1();
// do other stuff with low permission level
...
...
...
}
}
我已将辅助方法放在专用的强名称程序集中,并使用[SecuritySafeCritical]标记它们及其容器类:
// HelperAssembly.dll
namespace HelperAssembly
{
[SecuritySafeCritical]
public class HelperMethods
{
[SecuritySafeCritical]
public static void Method1()
{
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)
.Assert();
try
{
// logic requiring unmanaged code
...
}
finally
{
CodeAccessSecurity.RevertAll();
}
}
}
}
然后,我在沙箱AppDomain中加载帮助程序集并运行Proxy.DoStuff(),期望它执行辅助方法并继续运行:
var appDomain = CreateSandbox();
appDomain.Load(typeof(HelperAssembly.HelperMethods).Assembly.FullName);
var proxy = (Proxy)sandbox.CreateInstance(
typeof(Proxy).Assembly.FullName,
typeof(Proxy).FullName).Unwrap();
proxy.DoStuff();
但是,运行代码会导致辅助方法中的Assert()行出现异常:
未处理的异常:System.InvalidOperationException:无法在安全透明方法中执行CAS断言
这种行为的原因是什么?我如何实现我的目标?据我所知,不受信任的AppDomain中的代码是安全透明的,而帮助程序集中的代码是安全性安全的,这意味着它应该能够使用Assert()来请求权限。
我显然错过了一个难题,因此需要对代码访问安全有更好理解的人才能解释出现了什么问题。任何帮助表示赞赏。
答案 0 :(得分:4)
您的“受信任”程序集需要AllowPartiallyTrustedCallers
SecuritySafeCritical
属性才能在程序集边界内调用。它还必须添加到您对fullTrustAssemblies
的调用中的CreateDomain
。