2015-04-17 7 views
4

J'ai une API web asp.net qui a une logique pour exécuter certaines DLL générées dynamiquement. Je veux créer un nouvel AppDomain sandbox avec un jeu de permissions restreint pour exécuter ces DLL.Pourquoi un nouveau AppDomain charge-t-il des DLL inutiles?

Ceci est la méthode pour créer un nouveau appdomain restreint:

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; 
} 

Le problème que j'ai est la première fois que je référence à la nouvelle appdomain, par exemple juste pour lire le appDomain.FriendlyName, le framework tente de charger quelques dépendances présentes dans l'application en cours vers le nouveau AppDomain. Si les dépendances ne sont pas dans GAC, il essayera de les trouver dans l'applicationBasePath, et il échouera parce que l'applicationBasePath est définie sur un dossier qui stocke uniquement les DLL non fiables.

Ma question est pourquoi créer un nouveau AppDomain déclenche le chargement de ces dépendances supplémentaires. Dans ma méthode CreateRestrictedDomain ci-dessus, il n'y a aucune référence à l'une de ces dépendances.

J'ai créé un nouveau projet asp.net en utilisant le modèle par défaut dans VS 2013, et dans le contrôleur d'index je viens de créer un nouveau AppDomain en utilisant le code ci-dessus, et j'imprime le nom. Voici le code:

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(); 
} 

Quand je lance en mode débogage, je peux voir que la ligne qui a lu appDomain.FriendLyName déclencherait System.Web.dll à charger dans le nouveau 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. 

Pourquoi System.Web.dll doit-il être chargé dans le nouvel AppDomain?

Répondre

0

Il s'est avéré que parce que je crée un AppDomain à l'intérieur d'un AppDomain appartenant à ASP.NET. ASP.NET installe son propre AppDomainManager dans le AppDomain parent, ce qui est automatiquement propagée vers le bas à l'enfant AppDomains, sauf contrordre explicitement par l'appelant comme suit

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

Le passage à null pour securityInfo utilise la preuve de l'AppDomain en cours d'exécution.

AppDomain.CreateDomain:

securityInfo

Type: System.Security.Policy.Evidence

preuve établissant l'identité du code qui fonctionne dans le domaine d'application. Passez null pour utiliser la preuve du domaine d'application actuel.

Il est probable que l'assemblage System.Web.dll doive être chargé pour inspecter ses preuves.

+0

je suis passé la preuve: la preuve la preuve = De nouvelles preuves(); preuve.AddHostEvidence (nouvelle zone (SecurityZone.Untrusted)); à la méthode. Mais cela ne fait aucune différence. Je peux toujours voir System.Web.dll chargé dans le nouveau AppDomain. –