Подтвердить что ты не робот

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

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

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

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

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

Рабочий поток

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

<сильные > Преимущества

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

Недостатки

  • Нет песочницы - контроллеры будут иметь тот же уровень доверия, что и хост.

Заключение

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

Подход 2 - сборка MVC, работающая в собственном AppDomain через MAF

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

Структура

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

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

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

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

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

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

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

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

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

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

<сильные > Преимущества

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

Недостатки

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

Заключение

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

Вопросы

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

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

Некоторые вопросы у меня есть:

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

Ответ 1

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

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

Ответ 2

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

Любые альтернативы будут демонстрировать антипаттерн Inner Platform. Если у вас не будет много времени и денег, чтобы потратить на разработку плагиновую систему, вы собираетесь погрязнуть в ней и возмущаться ею. Я говорю по опыту.

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

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

Удачи!