限制插件汇编代码访问

时间:2009-10-05 13:35:17

标签: c# .net appdomain

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

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

3 个答案:

答案 0 :(得分:11)

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

  • 分离即可。如果需要,插件在他们自己的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 a-b;
    }
    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<AddInToken> 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<Calculator>(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

答案 1 :(得分:1)

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

你做的是这个:

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

答案 2 :(得分:0)

应该可以使用代码访问安全性。

我找到了这篇文章。

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

AppDomain政策级别将属于您

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