0

我想构建一个 WPF 系统,该系统可以包含由外部开发人员社区开发的插件。由于我不能为这些开发人员担保,我希望他们的代码在安全的环境中运行。看来 MAF 是一个很好的解决方案,所以我决定调查一下 MAF 的安全性。可以为每个插件定义一个精确的权限集,这非常好。

但是,我希望插件能够返回 WPF 控件。为此,他们需要能够运行 WPF 程序集。另外,我不希望插件能够运行非托管代码,这样它们就不能覆盖我在加载插件时设置的安全权限。

所以这就是问题所在 - 如果我在未经许可的情况下加载插件以运行非托管代码,那么插件将无法创建 WPF 控件。我怎么解决这个问题?

为了进一步测试这个问题,我编写了一个小型 WPF 应用程序,并尝试加载它并从第二个应用程序运行它。Bellow 是加载和运行 WPF 应用程序的代码。如果按原样,它会很好用,但是如果我删除最后一个 AddPermission 语句(带有 UnmanageCode 标志的语句),它就会停止工作,说它无法创建 WPF 应用程序的窗口。

PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess, PATH));
set.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
set.AddPermission(new UIPermission(PermissionState.Unrestricted));
set.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode));

Evidence ev = new Evidence();
AppDomain domain = AppDomain.CreateDomain("Test", ev, new AppDomainSetup() { ApplicationBase = PATH }, set);
domain.ExecuteAssembly(PATH);
4

2 回答 2

0

它对我有用,我认为问题在于您如何激活插件。尽量不要自己创建 AppDomain。您的代码应如下所示:

PermissionSet set = new PermissionSet(PermissionState.None);
set.AddPermission(new FileIOPermission(FileIOPermissionAccess.AllAccess, PATH));
set.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
set.AddPermission(new UIPermission(PermissionState.Unrestricted));

// .. retreive the addin token
var plugin = token.Activate<IMyPluginInterface>(set);

当我以前以这种方式创建插件时,它对我有用。它也是一个 wpf UI。

于 2013-09-24T06:00:58.933 回答
0

您是否查看过 CreateDomain 方法的这种重载?您可以设置一些将被视为完全信任的组件。

如果您查看 System.AddIn 源代码(可在此处找到),您将看到在文件 AddInActivator.cs 中,他们使用从 System.AddIn 程序集获取的AssemblyName中获取的StrongNamePublicKeyBlob创建了StrongName的实例。

因此,也许您可​​以对 PresentationCore 和 System.Windows.Presentation 或您想要授予完全信任的任何其他程序集执行相同的操作。

例如,您可以试试这个(从 AddInActivator.cs 中几乎逐字记录):

//assembly is the Assembly object you want to grant full trust permissions.
AssemblyName assemblyName = assembly.GetName();

// get the public key blob
byte[] publicKey = assemblyName.GetPublicKey(); 
if (publicKey == null || publicKey.Length == 0)
    throw new InvalidOperationException(Res.NoStrongName);

StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey); 

// and create the StrongName 
StrongName strongName = new StrongName(keyBlob, assemblyName.Name, assemblyName.Version); 
// then call the overload of CreatDomain that takes a StrongName object parametes.
于 2012-06-05T12:08:23.410 回答