在.NET Web应用程序中实现不受信任的插件

Rat*_*eek 13 .net architecture plugins add-in

我想开发一个接受用户社区插件的应用程序,类似于Chrome或Firefox的插件.这将是一个Web应用程序,因此单个用户的应用程序的每个"实例"将运行不同的插件(插件将作为单例实例加载,但仅对某些用户"活动").我打算在.NET中实现应用程序,并试图为插件模型提出一个体系结构.

这是我想要的属性:

  • 插件完全在我的核心应用程序之外构建,作为单独的程序集.
  • 插件运行在他们自己的"锁定",低信任环境中.可能是一个单独的AppDomain.
  • 插件只能通过我提供的API进行操作.例如,我将它们作为接口传递给它们某种外观,并且它们只能调用它,而不是调用任何其他程序集.我不能拥有可以在Web服务器上任意执行操作的插件,例如影响文件系统.
  • 插件中的致命崩溃不会影响核心应用程序的稳定性.

似乎System.AddIn是我最好的选择,但我不清楚如何强制加载的插件只能通过我提供的API工作,而不是加载任何其他程序集.System.AddIn是否提供该功能?另外,System.AddIn可以与ASP.NET/IIS一起使用吗?

除了System.Addin,我还有什么其他选择?

mfe*_*old 5

看起来您主要关心的是隔离(为了安全性和稳健性).

因此,您最好的选择是在单独的AppDomain中激活您的插件.在此域中,您可以控制允许加载的程序集(请参阅AppDomainSetup类).

您的主要代码也将受到保护,免受插件内发生的任何不良事件的影响:所有插件方法都必须使用核心对象的副本(除非您传递的对象是从MarshalByRefObject继承的,在这种情况下所有的注意都是关闭的).addin方法中的例外可以通过将所有调用包装在try除外,或通过AppDomain的UnhandledExcption事件来处理.

请记住,跨越AppDomain边界会有性能损失.该呼叫本质上是一个远程呼叫.

另一个潜在的问题是您打算如何管理AppDomains.我从未试图在一个过程中创建多个AppDomain,但我希望在这里遇到麻烦.在单个域中为多个用户组合Addins将挑战您尝试构建的保护

响应@RationalGeek问题 - UnhandledException事件允许这样做 - 有点.您可以在核心域和插件域中订阅此事件,但这样做有很多不确定性 - 请参阅我引用的文章以获取更多详细信息.可能更好的选择是在try/except中包含对API的每次调用


Pat*_*uza 1

您可以尝试使用 AppDomains 并处理未处理的异常。为了避免 appdomain 崩溃,您必须处理AppDomain.UnhandledException

在上面的链接中,请注意以下声明

从 .NET Framework 4 开始,对于破坏进程状态的异常(例如堆栈溢出或访问冲突),不会引发此事件,除非事件处理程序是安全关键型的并且具有 HandleProcessCorruptedStateExceptionsAttribute 属性。

因此您可能需要显式处理一些配置。

我读过很多问题,声称当子域中的不同线程上发生未处理的异常时,会冒泡并导致父域崩溃。如果是这样,那么建议将所有插件加载到每个插件一个应用程序域的单独进程中,或者将插件加载到单独的进程中。

我还遇到了以下问题,我相信您会发现非常有帮助