【问题标题】:Why does a new AppDomain load unnecessary DLLs?为什么新的 AppDomain 会加载不必要的 DLL?
【发布时间】:2015-04-17 17:42:23
【问题描述】:

我有一个 asp.net web api,它具有执行一些动态生成的 DLL 的逻辑。 我想创建一个具有受限权限集的新沙盒 AppDomain 来执行这些 DLL。

这是创建新的受限应用域的方法:

public static AppDomain CreateRestrictedDomain(string applicationBasePath)
{
    PermissionSet permissionSet = new PermissionSet(PermissionState.None);
    permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
    permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, applicationBasePath));

    AppDomainSetup appDomainSetup = new AppDomainSetup
    {
        ApplicationBase = applicationBasePath,
        DisallowCodeDownload = true,
        DisallowBindingRedirects = true,
        DisallowPublisherPolicy = true,
        LoaderOptimization = LoaderOptimization.MultiDomainHost,
    };


    AppDomain restrictedDomain = AppDomain.CreateDomain(
        friendlyName: "MySandbox",
        securityInfo: null,
        info: appDomainSetup,
        grantSet: permissionSet,
        fullTrustAssemblies: null);

    return restrictedDomain;
}

我第一次引用新的appDomain时遇到的问题,例如只是为了读取 appDomain.FriendlyName,框架会尝试将当前应用程序中存在的一些依赖项加载到新的 AppDomain。如果依赖项不在 GAC 中,它会尝试在 applicationBasePath 中找到它们,并且会失败,因为 applicationBasePath 设置为仅存储不受信任的 DLL 的文件夹。

我的问题是为什么创建一个新的 AppDomain 会触发这些额外依赖项的加载。在我上面的 CreateRestrictedDomain 方法中,没有引用任何这些依赖项。

我在 VS 2013 中使用默认模板创建了一个新的 asp.net 项目,并在索引控制器中使用上面的代码创建了一个新的 AppDomain,并打印出名称。代码如下:

public ActionResult Index()
{
    var tempPath = Path.GetTempPath();
    var untrustedPath = Path.Combine(tempPath, "unstrusted");
    if (!Directory.Exists(untrustedPath))
    {
        Directory.CreateDirectory(untrustedPath);
    }
    var appDomain = AppDomainSandboxHelper.CreateRestrictedDomain(untrustedPath);
    var friendlyName = appDomain.FriendlyName;
    ViewBag.Title = friendlyName;

    return View();
}

当我在调试模式下运行时,我可以看到读取 appDomain.FriendLyName 的行会触发 System.Web.dll 被加载到新的 AppDomain "MySandbox"

'iisexpress.exe' (CLR v4.0.30319: Domain 4): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'. Symbols loaded.

'iisexpress.exe' (CLR v4.0.30319: MySandbox): Loaded 'C:\windows\Microsoft.Net\assembly\GAC_64\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll'. Symbols loaded.

为什么 System.Web.dll 需要加载到新的 AppDomain 中?

【问题讨论】:

    标签: c# asp.net .net-assembly appdomain


    【解决方案1】:

    securityInfo 传递null 使用当前正在执行的AppDomain 的证据。

    AppDomain.CreateDomain:

    安全信息

    类型:System.Security.Policy.Evidence

    确定在应用程序域中运行的代码的身份的证据。传递 null 以使用当前的证据 应用领域。

    很可能需要加载 System.Web.dll 程序集以检查其证据。

    【讨论】:

    • 我通过了证据:Evidence evidence = new Evidence();证据.AddHostEvidence(新区域(SecurityZone.Untrusted));到方法。但这没有任何区别。我仍然可以看到 System.Web.dll 加载到新的 AppDomain 中。
    【解决方案2】:

    原来是因为我在现有的 ASP.NET 拥有的 AppDomain 中创建了一个 AppDomain。 ASP.NET 将其自己的 AppDomainManager 安装到父 AppDomain 中,并且这会自动向下传播到子 AppDomain,除非调用者显式覆盖,如下所示

    AppDomainSetup appDomainSetup = new AppDomainSetup
    {
        ApplicationBase = applicationBasePath,
        DisallowCodeDownload = true,
        DisallowBindingRedirects = true,
        DisallowPublisherPolicy = true,
        LoaderOptimization = LoaderOptimization.MultiDomainHost,
        AppDomainManagerAssembly = "", // overridden by caller
        AppDomainManagerType = "" // overridden by caller
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多