受限应用程序域中的代码访问安全性例外



目标:我需要在权限非常有限的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(( 行出现异常:

未处理的异常:系统。无效操作异常:无法在安全透明方法中执行 CAS 断言

这种行为的原因是什么,我怎样才能实现我想要做的事情?据我了解,不受信任的 AppDomain 中的代码是安全透明的,而帮助程序程序集中的代码是安全安全的,这意味着它应该能够使用 Assert(( 请求权限。

我显然错过了一块拼图,所以由对代码访问安全性有更好理解的人来解释出了什么问题。任何帮助,不胜感激。

"受信任"程序集需要具有 AllowPartiallyTrustedCallers 属性,SecuritySafeCritical才能跨程序集边界调用。还必须将其添加到fullTrustAssemblies中,以调用CreateDomain

最新更新