由于过时的CAS策略,寻求替代AppDomain.CreateDomain(字符串,证据)

时间:2011-01-28 04:05:13

标签: c# .net-4.0 appdomain privileges code-access-security

我正在使用Microsoft .Net Framework - 应用程序开发基础培训工具包第8章第2课:配置应用程序域

ShowWinIni是我想要执行的程序的程序集名称

object[] hostEvidence = { new Zone(SecurityZone.MyComputer) };
Evidence e = new Evidence(hostEvidence, null);

// Create an AppDomain.
AppDomain d = AppDomain.CreateDomain("New Domain", e);

// Run the assembly
d.ExecuteAssemblyByName("ShowWinIni");

执行时:

AppDomain d = AppDomain.CreateDomain("New Domain", e);

我收到以下消息: “此方法隐式使用CAS策略,已被.NET Framework废弃。为了出于兼容性原因启用CAS策略,请使用NetFx40_LegacySecurityPolicy配置开关。有关详细信息,请参阅http://go.microsoft.com/fwlink/?LinkID=155570。”

当我创建一个没有Evidence对象的AppDomain时,我可以正常执行程序集。

当然,我访问了http://go.microsoft.com/fwlink/?LinkID=155570,但我仍然对如何创建具有指定权限的应用程序域感到困惑。

我找到的下一个最有用的网站是http://msdn.microsoft.com/en-us/library/bb763046.aspx,但我的StrongName对象计算为NULL。

StrongName fullTrustAssembly =
     typeof(Program).Assembly.Evidence.GetHostEvidence<StrongName>();

程序是实现所有代码的类的名称。

提前感谢您的建议和提示!

2 个答案:

答案 0 :(得分:11)

我找到了一种方法,可以使原始代码示例无需启用NetFX40_LegacySecurityPolicy。

EvidenceBase[] hostEvidence = { new Zone(SecurityZone.MyComputer) };
Evidence e = new Evidence(hostEvidence, null);

AppDomain d = AppDomain.CreateDomain("New Domain", e);

d.ExecuteAssemblyByName("ShowWinIni");

如果您将SecurityZone更改为Internet,它将无法使用,它将尝试使用过时的CAS安全策略,从而导致出现NotSupportedException。我想要的是SecurityException ...这意味着我想要执行的程序集没有它需要的权限。

要在具有受限权限的AppDomain中执行程序集,您需要使用沙盒。我找到的最好的沙盒示例如下: http://www.simple-talk.com/dotnet/.net-framework/whats-new-in-code-access-security-in-.net-framework-4.0---part-i/

我认为该页面也很好地解释了对4.0中CAS的更改!

许多来源,包括MSDN,让我确信在调用时需要提供一个StrongName数组:

AppDomain.CreateDomain( string friendlyName,
                        Evidence securityInfo,
                        AppDomainSetup info,
                        PermissionSet grantSet,
                        params StrongName[] fullTrustAssemblies);

正如我在原帖中所述,我(现在仍然)无法获取StrongName对象而不是null。事实证明我甚至不需要它!

这是我完成的沙盒示例:

Evidence ev = new Evidence();
ev.AddHostEvidence(new Zone(SecurityZone.Internet));
PermissionSet internetPS = SecurityManager.GetStandardSandbox(ev);

AppDomainSetup adSetup = new AppDomainSetup();
adSetup.ApplicationBase = Path.GetFullPath(pathToUntrusted);

AppDomain newDomain = AppDomain.CreateDomain("Sandbox Domain", null, adSetup, internetPS);

newDomain.ExecuteAssemblyByName(untrustedAssembly);

pathToUntrusted =程序集文件路径的字符串表示

untrustedAssembly =程序集名称

的字符串表示形式

答案 1 :(得分:7)

在寻求同事的帮助后,我得到了这个工作。

显然,这本书的练习是为了在.Net的3.5框架中使用而设计的,而我使用的是4.0。修改我的项目和ShowWinIni项目属性以使用3.5框架后,一切正常......但我仍然希望使用4.0框架。

要解决以下消息: &#34;此方法隐式使用CAS策略,该策略已被.NET Framework废弃。为了兼容性原因启用CAS策略,请使用NetFx40_LegacySecurityPolicy配置开关。有关详细信息,请参阅http://go.microsoft.com/fwlink/?LinkID=155570。&#34;

我创建了一个app.config文件并添加了以下内容:

<configuration>
   <runtime>
      <NetFx40_LegacySecurityPolicy enabled="true"/>
   </runtime>
</configuration>

您可以在http://msdn.microsoft.com/en-us/library/dd409253.aspx了解有关NetFx40_LegacySecurityPolicy的更多信息

这最终导致我的程序成为不受信任的应用程序,在我尝试调试时抛出了安全异常。为了使我的应用程序再次可靠,我启用了ClickOnce安全设置并标记了&#34;这是一个完全信任的应用程序&#34;在我项目的属性中。

此时,我可以调试我的程序,但是当我执行此语句时,现在抛出了一个Security Exception:

d.ExecuteAssemblyByName("ShowWinIni");

在我创建AppDomain对象时,在开始尝试包含Evidence对象之前,此语句运行正常。好吧,事实证明还有另一种方法...... AppDomain.ExecuteAssemblyByName(字符串,证据),你可以在http://msdn.microsoft.com/en-us/library/5kd4z003.aspx阅读。所以我用以下内容替换了上面的代码片段:

d.ExecuteAssemblyByName("ShowWinIni", e);

&#39; E&#39;是我原始问题中创建的Evidence对象。

现在我不认为这是最好的解决方案。理想情况下,我宁愿不强迫我的程序使用NetFx40_LegacySecurityPolicy,我相信真实世界的应用程序不应该依赖于过时的方法。如果有人和我一起工作,我认为这个解决方案值得发布。