【问题标题】:Code Access Security exception in restricted AppDomain受限 AppDomain 中的代码访问安全异常
【发布时间】:2013-10-06 19:13:19
【问题描述】:

目标:我需要在 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() 请求权限。

我显然遗漏了一块拼图,因此由对代码访问安全性有更好理解的人来解释出了什么问题。任何帮助表示赞赏。

【问题讨论】:

  • 您的受信任程序集是否具有 AllowPartiallyTrustedCallers 属性? IIRC 它用于 SecuritySafeCritical 的东西......另外,你没有使用 CreateDomainfullTrustAssemblies 参数。这正常吗?
  • [SecuritySafeCritical] 属性将被忽略,除非您对程序集进行强命名。项目 + 属性,签名选项卡。
  • @Medinoc,正确!我需要在 AppDomain.Create 中添加受信任的辅助程序集,并将其标记为 [AllowPartiallyTrustedCallers]。请将您的评论推广到答案,以便我将其标记为正确。
  • @HansPassant,感谢您的意见。你是对的,但是在这种情况下,辅助程序集 强命名的(我在问题中提到了它,但也许我应该加粗它)。

标签: c# appdomain code-access-security


【解决方案1】:

您的“受信任”程序集需要具有 AllowPartiallyTrustedCallers 属性,以便 SecuritySafeCritical 可以跨程序集边界调用。在您对CreateDomain 的调用中,它还必须添加到fullTrustAssemblies

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2014-08-26
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多