11

我正在阅读 Microsoft .Net Framework--Application Development Foundation Training Kit 书第 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);

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

当我创建一个没有证据对象的 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>();

Program 是实现所有这些代码的类的名称。

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

4

2 回答 2

12

我找到了一种无需启用 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= 程序集名称的字符串表示形式

于 2011-02-07T17:37:21.360 回答
7

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

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

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

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

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

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

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

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

d.ExecuteAssemblyByName("ShowWinIni");

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

d.ExecuteAssemblyByName("ShowWinIni", e);

'e' 是我在原始问题中创建的证据对象。

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

于 2011-01-29T15:36:13.717 回答