Поиск альтернативы AppDomain.CreateDomain(строка, доказательство) из-за устаревшей политики CAS

Я работаю через 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 для получения дополнительной информации."

Я могу выполнить сборку отлично, когда создаю AppDomain без объекта Evidence.

Конечно, я посетил 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>();

Программа - это имя класса, реализующего весь этот код.

Заранее благодарим за советы и советы!

Ответ 1

Я нашел способ сделать пример исходного кода работать без необходимости включать 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 на Интернет, он попытается использовать устаревшую политику безопасности 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/

Я думаю, что страница также объясняет изменения, внесенные в CAS в 4.0 очень хорошо!

Многие источники, включая 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= строковое представление имени сборки

Ответ 2

После обращения за помощью к коллегам я получил эту работу.

Очевидно, учебное упражнение было разработано для использования в .Net 3.5 framework, в то время как я использую 4.0. После изменения как моего проекта, так и свойств проекта ShowWinIni использовать фреймворк 3.5 все сработало... но я все еще хотел сделать эту работу с рамкой 4.0.

Чтобы обратиться к следующему сообщению: "Этот метод неявно использует политику CAS, которая устарела .NET Framework. Чтобы включить политику CAS для соображений совместимости, используйте переключатель конфигурации NetFx40_LegacySecurityPolicy. См. http://go.microsoft.com/fwlink/?LinkID=155570 для получения дополнительной информации."

Я создал файл app.config и добавил к нему следующее:

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

Подробнее о NetFx40_LegacySecurityPolicy вы можете узнать по адресу http://msdn.microsoft.com/en-us/library/dd409253.aspx

Это закончилось тем, что моя программа была ненадежным приложением, бросая исключение безопасности, когда я пытался отлаживать. Чтобы снова сделать мое приложение надежным, я включил параметры безопасности ClickOnce и пометил "Это приложение полного доверия" в моих свойствах проекта.

На этом этапе я мог бы отлаживать мою программу, но при выполнении этого оператора было исключено исключение безопасности:

d.ExecuteAssemblyByName("ShowWinIni");

Этот оператор работал отлично, прежде чем я начал пытаться включить объект Evidence, когда создал свой объект AppDomain. Ну, получается, что есть другой метод... AppDomain.ExecuteAssemblyByName(строка, доказательство), вы можете прочитать в http://msdn.microsoft.com/en-us/library/5kd4z003.aspx. Поэтому я заменил приведенный выше фрагмент кода следующим текстом:

d.ExecuteAssemblyByName("ShowWinIni", e);

'e' - мой объект Evidence, созданный в моем первоначальном вопросе.

Теперь я НЕ думаю, что это лучшее решение. В идеале я бы предпочел не заставить мою программу использовать NetFx40_LegacySecurityPolicy, и я считаю, что приложения реального мира не должны полагаться на устаревшие методы. Я думал, что это решение стоит публикации, если кто-то будет работать через ту же книгу, что и я.