在新的Appdomain中加载程序集,需要完全信任父程序集

时间:2017-09-24 17:36:20

标签: c# .net security .net-assembly

我在主应用程序中运行宏程序集。宏不需要访问父程序集。这是片段:

Assembly ParentAssembly
{
    class c1
    { 
        void RunMacro()  
        {
            System.Security.PermissionSet PS = new System.Security.PermissionSet(PermissionState.None);
            PS.AddPermission(new SOME_PERMISSIONS....);
            AppDomainSetup ADS = new AppDomainSetup();
            ADS.ApplicationBase = "c:";
            AppDomain domain = AppDomain.CreateDomain(SomeName, null, ADS, PS);

            System.Runtime.Remoting.ObjectHandle handle = Activator.CreateInstanceFrom(domain, typeof(Sandboxer2).Assembly.ManifestModule.FullyQualifiedName, typeof(Sandboxer2).FullName);
            Sandboxer2 m = (Sandboxer2)handle.Unwrap();
            m.Execute();
        }
    }
}

我收到此例外:

  

尝试安全透明方法   'SandBoxer.Sandboxer2.Execute()'访问安全关键方法   'System.AppDomain.add_AssemblyResolve(System.ResolveEventHandler)'   失败。

     

程序集'父程序集全名...'部分受信任,其中   导致CLR使其完全安全透明,无论如何   程序集本身中的任何透明度注释。为了   访问安全关键代码,必须完全信任此程序集。

我的问题:

  1. 有没有办法避免在子程序集中加载父程序集?

  2. 在我的代码的第二行,哪些权限可以解决问题?

  3. 有些程序集将在运行时由SandBoxer的AssemblyResolve事件加载。程序集从数据库作为二进制数组或从GAC加载。他们并不完全信任。我使用在第二行代码中添加的权限对象来控制他们的行为。我是否需要添加特殊权限才能将它们仅作为部分受信任的程序集加载?

  4. 我认为一切都可以通过添加第二行代码等安全权限来完成,如果我误解了这个概念,我将非常感激被引导。

    EDIT1: Parent Assembly是创建SandBoxr实例并运行它的主应用程序的程序集。请看一下SandBoxer2类及其Execute方法:

    public class Sandboxer2 : MarshalByRefObject
    {
        public void Execute()
        {
            AppDomain ad = AppDomain.CurrentDomain;
            ad.AssemblyResolve += MyHandler;
            .
            .
            .
        }
    }
    

    在Execute方法内部,在实例化广告后,我使用了ad.GetAssemblies(),这是已加载的所有程序集的列表。第2行从沙箱的执行开始就保存了ParentAssembly。

      
        
    • [0] {mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [1] {System.Web,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [2] {ParentAssembly,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [3] {System.Data,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [4] {System,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [5] {MacroBase_IO,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [6] {System.Core,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [7] {System.Configuration,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   
    • [8] {System.Xml,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089} System.Reflection.Assembly   {System.Reflection.RuntimeAssembly}
    •   

1 个答案:

答案 0 :(得分:0)

回答问题1和2:

Sandboxer必须位于单独的程序集(另一个DLL)中,并且必须使用密钥对此单独的程序集进行签名。然后,不会自动加载主应用程序,也不会引发此异常。

编辑:

1-使用密钥签名是通过“程序集签名”选项卡完成的。

2-这个sample有助于理解如何将程序集定义为完全信任,并为Sandbox引入强名称。