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