System.Addin - Создание защищенных плагинов ASP.NET MVC

В последнее время я сосредоточился на создании приложения ASP.NET MVC, в котором могут размещаться сторонние плагины MVC. В идеале разработка этих плагинов должна следовать следующим правилам:

  1. Плагины могут быть разработаны в стандартном проекте MVC и могут использовать всю существующую инфраструктуру инфраструктуры ASP.NET MVC.
  2. Сложность компиляции проекта MVC плагина и включения его в приложение MVC хоста не должно быть серьезным.
  3. Любые изменения в нормальном потоке разработки приложения MVC будут минимальным

После некоторого исследования я придумал следующие подходы для достижения этой цели, каждый из которых имеет свои преимущества и недостатки.

Подход 1 - сборка плагина MVC, загруженная в основной домен приложения MVC

Рабочий процесс

  • Разработайте плагин внутри отдельного проекта MVC.
  • Скомпилируйте сборку и загрузите ее и все зависимости в хост-приложение через PreApplicationStartMethodAttribute, MEF или базовая ссылка на сборку в хост-проекте (если это возможно).
  • Сопоставьте маршрут с контроллерами плагинов, чтобы плагин рассматривался как Area внутри хозяина
  • Поместите виды плагинов в правильную папку области. Файл макета необходимо будет изменить таким образом, чтобы путь макета указывал на местоположение на основе области, а не на корень приложения (что было бы в случае с проектом MVC разработки)
  • Когда поступает запрос на плагин, ASP.NET будет использовать функциональность существующих областей, чтобы направить запрос на правильные контроллеры и найти правильное расположение для файлов просмотра.

преимущества

  1. Будет работать так же легко, как если бы контроллеры были встроены в сборку приложения MVC хоста.
  2. Просто включить сборки в хост-домен приложения перед запуском приложения (PreApplicationStartMethodAttribute, ссылка на проект) и после запуска приложения (MEF)

Недостатки

  1. Без песочницы - у контроллеров будет тот же уровень доверия, что и у хоста.

Заключение

Это самый простой подход, но он также наименее безопасный. Это по существу исключает возможность создания ненадежными разработчиками плагинов, поскольку эти плагины будут иметь тот же уровень доверия, что и хост-приложение (это означает, что если хост-приложение может выполнять такие методы, как System.IO.File.Deleteтак же может плагин)

Подход 2 - сборка плагина MVC, работающая в собственном домене приложений через MAF

Этот подход позволяет создавать плагины MVC, которые можно помещать в свои собственные AppDomains и используется хостом через System.Addin библиотеки.

Состав

  1. В хосте настраивается маршрут, который определяет, нацелен ли обрабатываемый URL на плагин. Может иметь такой шаблон, как example.com/p/{plugin}/{controller}/{action}/{id}

  2. Все маршруты с указанным выше шаблоном сопоставляются с хост-контроллером, который выполняет действие маршрутизации модуля. Это действие просматривает любой данный маршрут и определяет соответствующий плагин для обработки запроса на основе {plugin} сегмент.

  3. Представление плагина - это объект получателя / отправителя, который действует как шлюз для контроллеров плагина. У него есть метод AcceptRequest, который получает RequestContext от хоста, и это возвращает ActionResult,

  4. Плагин конвейера содержит адаптеры, которые могут сериализовать RequestContext а также ActionResult для передачи через границу изоляции трубопровода.

Выполнение потока

  1. Маршрут для плагина совпадает, и вызывается контроллер маршрутизации плагина.

  2. Контроллер загружает нужный плагин в свой AppDomain и вызывает AcceptRequest, проходя через RequestContext (который сериализуется через конвейер)

  3. AcceptRequest получает контекст и определяет соответствующий контроллер для выполнения на основе этого запроса (используя фабрику пользовательских контроллеров).

  4. Как только контроллер завершил выполнение запроса, он возвращает ActionResult к объекту-получателю, который затем передал это ActionResult (также сериализуется через конвейер) обратно к хосту AppDomain,

  5. Контроллер, который первоначально вызвал AcceptRequest, может затем вернуть ActionResult к конвейеру выполнения MVC узла, как если бы он обрабатывал сам запрос. Плагин AppDomain затем может быть выгружен, если пожелает.

преимущества

Плагин будет помещен в AppDomainТаким образом, можно использовать любой набор разрешений, который подходит хосту.

Недостатки

  • Должна быть возможность сериализации RequestContext а также ActionResult,
  • Возможно, нарушит другие функции ASP.NET MVC в изолированной AppDomain,

Заключение

Этот подход звучит хорошо на бумаге, но я не уверен, что возможно / возможно сериализовать RequestContext а также ActionResult объекты, а также запустить контроллер MVC в изоляции.

Вопросы

Первый подход хорош, если код создается доверенными разработчиками. Я знаю, что я не собираюсь удалять все файлы представления хоста или его файл web.config. Но, в конечном счете, если вы хотите, чтобы сторонние разработчики создавали плагины для вашего MVC-приложения, вы должны быть в состоянии изолировать их код.

Из всех моих исследований, System.Addin библиотека облегчает реализацию среды хоста / плагина, когда вы используете простые библиотеки классов на основе API. Однако, кажется, что это нелегко сделать, когда задействован MVC.

У меня есть несколько вопросов:

  1. Возможен ли второй подход, который я изложил здесь?
  2. Есть лучший способ сделать это?
  3. Будут ли в будущем более простые способы изоляции плагинов MVC?

2 ответа

В итоге вы создадите отдельные сайты для каждого плагина. Таким образом, вы можете создавать пользователей с ограниченными правами для каждого AppPool, а системный администратор может установить "плагин" как веб-сайт, работающий под этим пользователем.

Любые альтернативы будут выставлять Антипаттерн Внутренней Платформы. Если у вас не будет много времени и денег, чтобы потратить на разработку системы хостинга плагинов, вы будете увязать в этом и обижаться на него. Я говорю из опыта.

Сайты могут совместно использовать пользовательские репозитории AspnetIdentity, и вы можете предоставить свои основные объекты в виде библиотеки DLL, на которую можно ссылаться. Разместите ваш контент (файлы сценариев, CSS, изображения) в CDN, чтобы на них можно было ссылаться. Если вы хотите поделиться взглядами со своими дочерними сайтами, скомпилируйте их в виде ресурсов:

Включение предварительно скомпилированных представлений в веб-приложение ASP.NET MVC

Удачи!

IMHO System.AddIn немного излишне для того, что вы пытаетесь сделать.

Вы знакомы с пространством имен System.Security.Permissions? Если нет, вы можете взглянуть на FileIOPermission. Возможно, вы могли бы изолировать свою расширяемую систему, используя (и даже не расширяя) механизм безопасности доступа к коду.NET.

Другие вопросы по тегам