限制插件汇编代码访问

我想创建一个插件架构,我可以将程序集API限制为非常有限的内容,即只允许函数白名单。 是否可以限制插件组件可以调用的function/方法? 我可以使用AppDomains吗?

有没有人有一个简单的例子?

.NET已经添加了可能适合该法案的“托管插件框架”。 它具有以下function:

  • 隔离 。 如果需要,插件可以在自己的AppDomain中运行,如果需要这种级别的隔离,甚至可以使用自己的进程
  • 合同沟通 。 您设置合同,这是您向插件作者分发的唯一内容。 他们不需要知道您的申请的任何其他方面。
  • 发现 。 有一个内置机制,用于从一个装满程序集的文件夹中嗅出插件。
  • 安全 。 加载插件时会自动应用CASPOL集。 内置了一些选项可以轻松实现(请参阅AddInSecurityLevel Enum )。

大多数隔离方法也限制了通信和UI集成。 MAF试图绕过这些限制。 它要求您设置合同通信管道,但是将执行您通常必须自己完成的大部分工作。

一个例子是将两个独立进程中运行的UI片段拼接在一起(这很神奇),或者能够在AppDomain或进程中引发事件。 这些事情并非无足轻重,但MAF在这方面帮助很大。

样品

这是一个简单的例子。 作为“Shell”作者,您将向插件作者提供合同。 这是一个典型的合同(它只是一个抽象类):

public abstract class Calculator { public abstract double Add(double a, double b); public abstract double Subtract(double a, double b); public abstract double Multiply(double a, double b); public abstract double Divide(double a, double b); } 

如果插件作者想要编写插件,他们只会将此合约子类化并添加“Addin”属性:

 [AddIn("Sample Calculator AddIn", Version="1.0.0.0")] public class SampleCalculatorAddIn : Calculator { public override double Add(double a, double b) { return a + b; } public override double Subtract(double a, double b) { return ab; } public override double Multiply(double a, double b) { return a * b; } public override double Divide(double a, double b) { return a / b; } } 

以下是加载这些插件并与之交互的方法:

 // In this sample we expect the AddIns and components to // be installed in the current directory String addInRoot = Environment.CurrentDirectory; // Check to see if new AddIns have been installed AddInStore.Rebuild(addInRoot); // Look for Calculator AddIns in our root directory and // store the results Collection tokens = AddInStore.FindAddIns(typeof(Calculator), addInRoot); // Ask the user which AddIn they would like to use AddInToken calcToken = ChooseCalculator(tokens); // Activate the selected AddInToken in a new AppDomain set sandboxed // in the internet zone. You can find out what this gives access // to by running "mscorcfg.msc", but essentially this will limit // any access to the filesystem and other obvious OS services. // Use of reflection is also very limited in this zone. Calculator calculator = calcToken.Activate(AddInSecurityLevel.Internet); // Run the read-eval-print loop RunCalculator(calculator); 

这几乎就是要点。 显然还有更多,但你明白了。

进一步阅读

好的介绍文章
https://web-beta.archive.org/web/20140820145919/http://msdn.microsoft.com/en-us/magazine/cc163476.aspx

MSDN概述
http://msdn.microsoft.com/en-us/library/bb384200.aspx

Codeplex上的System.Addin(大量样本)
http://www.codeplex.com/clraddins

工具

Pipeline Builder (有助于在shell和插件之间生成通信管道)
http://clraddins.codeplex.com/wikipage?title=Pipeline%20Builder&referringTitle=Home

System.Addin的Fx-Cop规则
http://clraddins.codeplex.com/wikipage?title=Add-in%20FxCop%20Rules&referringTitle=Home

使用internal关键字anytihng你不希望其他程序集看到应该工作。 我错过了什么吗?

你做的是这样的:

  • 将所有“完全权限”项目设为内部
  • 在AssemblyInfo.cs中,为您完全信任的每个程序集添加InternalsVisibleTo属性。 代码示例: [InternalsVisibleTo("fullNameOfAssemblyFromOtherLibrariesAssemblyInfoFile")]
  • Ta-da,您的所有代码都是安全的! (除非反思,你无论如何都无法阻止)

它应该可以使用Code Access Security。

我找到了这篇文章。

http://www.15seconds.com/Issue/040121.htm

AppDomain政策级别将是您的

编辑:提供示例代码非常复杂。 但是MSDN应该给你一些好的提示: http : //msdn.microsoft.com/en-us/library/yctbsyf4(VS.71).aspx