Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
System.Addin-创建安全的ASP.NET MVC插件_Asp.net_Asp.net Mvc_Plugins_Appdomain - Fatal编程技术网

System.Addin-创建安全的ASP.NET MVC插件

System.Addin-创建安全的ASP.NET MVC插件,asp.net,asp.net-mvc,plugins,appdomain,Asp.net,Asp.net Mvc,Plugins,Appdomain,最近我的重点是创建一个ASP.NET MVC应用程序,它可以承载第三方MVC插件。理想情况下,这些插件的开发将遵循以下规则: 插件可以在标准MVC项目中开发,并且能够使用ASP.NET MVC框架的所有现有基础设施 编译插件MVC项目并将其包含到宿主MVC应用程序中的复杂性应该不会很高 对MVC应用程序的正常开发流程的任何更改都是最低限度的 经过一些研究,我提出了以下方法来实现这一点,每种方法都有各自的优点和缺点 方法1-MVC插件程序集加载到主MVC AppDomain 工作流程 在单独的M

最近我的重点是创建一个ASP.NET MVC应用程序,它可以承载第三方MVC插件。理想情况下,这些插件的开发将遵循以下规则:

  • 插件可以在标准MVC项目中开发,并且能够使用ASP.NET MVC框架的所有现有基础设施
  • 编译插件MVC项目并将其包含到宿主MVC应用程序中的复杂性应该不会很高
  • 对MVC应用程序的正常开发流程的任何更改都是最低限度的
  • 经过一些研究,我提出了以下方法来实现这一点,每种方法都有各自的优点和缺点

    方法1-MVC插件程序集加载到主MVC AppDomain 工作流程

    • 在单独的MVC项目中开发插件
    • 编译程序集并通过主项目中的
      PreApplicationStartMethodAttribute
      MEF或基本程序集引用(如果可能)将其和任何依赖项加载到主应用程序中
    • 将路径映射到插件控制器,以便插件被视为主机内的
      区域
    • 将插件视图放入正确的区域文件夹中。布局文件需要更改,以便布局路径指向基于区域的位置,而不是应用程序的根(在开发MVC项目中就是这种情况)
    • 当插件请求进来时,ASP.NET将使用现有区域功能将请求路由到正确的控制器,并在正确的位置查找视图文件
    优势

  • 将像控制器嵌入主机MVC应用程序部件一样无缝工作
  • 在应用程序启动之前(
    PreApplicationStartMethodAttribute
    ,项目参考)和应用程序启动之后(MEF),将程序集包含到宿主应用程序域中非常简单
  • 缺点

  • 无沙箱-控制器将具有与主机相同的信任级别
  • 结论

    这是最简单的方法,但也是最不安全的方法。它本质上消除了允许不受信任的开发人员创建插件的可能性,因为这些插件将具有与主机应用程序相同的信任级别(这意味着如果主机应用程序可以执行诸如
    System.IO.File.Delete
    ,那么插件也可以)

    方法2-通过MAF在自己的AppDomain中运行MVC插件程序集 此方法旨在允许创建MVC插件,这些插件可以被沙盒放入它们自己的
    AppDomains
    ,并由主机通过
    系统使用。Addin

    结构

  • 在主机中设置一个路由,用于确定正在处理的url是否以插件为目标。可能有一个模式,例如
    example.com/p/{plugin}/{controller}/{action}/{id}

  • 具有上述模式的所有路由都映射到具有模块路由操作的主机控制器。该操作查看任何给定的路由,并根据
    {plugin}
    段确定处理请求的适当插件

  • 插件视图是一个接收方/发送方对象,充当插件控制器的网关。它有一个名为AcceptRequest的方法,该方法从主机接收
    RequestContext
    ,并返回
    ActionResult

  • 插件管道包含可以序列化
    RequestContext
    ActionResult
    的适配器,以便跨管道的隔离边界进行传输

  • 执行流程

  • 匹配插件的路由,并调用插件路由控制器

  • 控制器将所需插件加载到自己的
    AppDomain
    中,并通过
    RequestContext
    (通过管道序列化)调用AcceptRequest

  • AcceptRequest接收上下文并根据该请求确定要执行的适当控制器(使用自定义控制器工厂)

  • 一旦控制器完成了请求的执行,它将向接收方对象返回一个
    ActionResult
    ,然后接收方对象将该
    ActionResult
    (也通过管道序列化)传递回主机
    AppDomain

  • 最初调用AcceptRequest的控制器可以将
    ActionResult
    返回到主机MVC执行管道,就好像它自己处理了请求一样。如果愿意,可以卸载插件AppDomain

  • 优势

    插件将被沙盒放在它的
    AppDomain
    中,因此可以使用适合主机的任何权限集

    缺点

    • 必须能够序列化
      RequestContext
      ActionResult
    • 可能会破坏隔离的
      AppDomain
      中的其他ASP.NET MVC功能
    结论

    这种方法在理论上听起来不错,但我不确定是否可能/可行序列化
    RequestContext
    ActionResult
    对象,以及单独运行MVC控制器

    问题 如果代码是由受信任的开发人员创建的,那么第一种方法就可以了。我知道我不会删除所有的主机视图文件或它的web.config文件。但最终,如果你想让第三方开发者为你的MVC应用程序创建插件,你需要能够对他们的代码进行沙箱处理

    根据我所有的研究,当您使用简单的基于API的CLA时,
    System.Addin
    库可以轻松实现主机/插件环境