限制插件汇编代码访问
Posted
技术标签:
【中文标题】限制插件汇编代码访问【英文标题】:Restrict plug-in assembly code access 【发布时间】:2009-10-05 13:35:16 【问题描述】:我想创建一个插件架构,我可以在其中将程序集 API 限制为非常受限的东西,即只允许函数的白名单。 是否可以限制插件程序集可以调用的功能/方法? 我可以使用 AppDomains 吗?
谁有一个简单的例子?
【问题讨论】:
你指的是哪些函数/方法?您的或 .NET Framework 函数? 两者都可以,如果需要,我可以将 .NET 封装在我的中。 重新编辑 InternalsVisibleTo 属性 【参考方案1】:.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
【讨论】:
【参考方案2】:使用internal
关键字来处理您不希望其他程序集看到的任何内容都应该有效。我错过了什么吗?
你要做的是:
将所有“完全权限”项目设为内部 在 AssemblyInfo.cs 中,为您完全信任的每个程序集添加 InternalsVisibleTo 属性。代码示例:[InternalsVisibleTo("fullNameOfAssemblyFromOtherLibrariesAssemblyInfoFile")]
Ta-da,你所有的代码都是安全的! (除了反射,无论如何你都不能真正停止)
【讨论】:
是的,我希望一些代码以完全权限运行,而其他代码以非常有限的权限集运行。使用 internal 会阻止所有程序集访问它,而不仅仅是插件程序。代码访问安全的方向是正确的,它回答了第一个/第二个问题,但没有回答第三个问题,即一个简单的例子。 我不明白。任何你想看到内部的东西,在你的原始程序集中设置 InternalsVisibleTo 属性。插件程序集没有这种能力,因此看不到任何需要“完全权限”的东西。我会用一些链接编辑我的答案。 您可以通过应用适当的 CASPOL 来限制反射的使用。【参考方案3】:代码访问安全应该是可能的。
我找到了这篇文章。
http://www.15seconds.com/Issue/040121.htm
AppDomain 策略级别将是您的
编辑:提供示例代码非常复杂。不过 MSDN 应该会给你一些好的提示:http://msdn.microsoft.com/en-us/library/yctbsyf4(VS.71).aspx
【讨论】:
这可行,但在完全信任的情况下,无论如何都会授予所有权限。 但是您可以配置一个信任度较低的 AppDomain 并在那里加载您的插件。 编辑我的答案:添加到 MSDN 的链接以上是关于限制插件汇编代码访问的主要内容,如果未能解决你的问题,请参考以下文章