asp.net - route - tag helpers asp net core
System.Addin-Creación de plugins ASP.NET MVC seguros (2)
En mi humilde opinión System.AddIn es un poco exagerado para lo que estás tratando de hacer.
¿Está familiarizado con el espacio de nombres System.Security.Permissions ? Si no, puede echar un vistazo a la FileIOPermission . Tal vez podrías poner a prueba tu sistema extensible usando (y por qué no, incluso extendiendo) el mecanismo de seguridad de acceso de código de .NET.
Últimamente mi objetivo ha sido crear una aplicación ASP.NET MVC que pueda alojar plugins MVC de terceros. Idealmente, el desarrollo de esos complementos seguiría estas reglas:
- Los complementos se pueden desarrollar en un proyecto MVC estándar y pueden usar toda la infraestructura existente del marco ASP.NET MVC.
- La complejidad de compilar el plugin MVC project e incluirlo en una aplicación host MVC no debe ser grave.
- Cualquier cambio en el flujo de desarrollo normal de una aplicación MVC sería el mínimo
Después de algunas investigaciones, he llegado a los siguientes enfoques para lograr esto, cada uno con sus propias ventajas y desventajas.
Enfoque 1: ensamblado de plugin MVC cargado en el AppDomain principal de MVC
Flujo de trabajo
- Desarrollar el plugin dentro de un proyecto separado de MVC.
- Compile el ensamblaje y cárguelo y cualquier dependencia en la aplicación de host mediante
PreApplicationStartMethodAttribute
, MEF o una referencia de ensamblaje básico dentro del proyecto de host (si es posible). - Asigne una ruta a los controladores de complementos para que el complemento se trate como un
Area
dentro del host. - Coloque las vistas del complemento en la carpeta del área correcta. El archivo de diseño deberá modificarse para que la ruta de diseño apunte a una ubicación basada en área, en lugar de a la raíz de la aplicación (lo que habría sido el caso en el proyecto MVC de desarrollo).
- Cuando aparece una solicitud para el complemento, ASP.NET utilizará la funcionalidad de áreas existentes para enrutar la solicitud a los controladores correctos y buscar en la ubicación correcta para los archivos de vista.
Ventajas
- Funcionará sin problemas como si los controladores estuvieran incrustados en el ensamblado de la aplicación MVC del host.
- Sencillo de incluir los ensamblajes en el dominio de la aplicación host antes del inicio de la aplicación (
PreApplicationStartMethodAttribute
, referencia del proyecto) y después del inicio de la aplicación ( MEF )
Desventajas
- Sin sandboxing: los controladores tendrán el mismo nivel de confianza que el host.
Conclusión
Este es el enfoque más fácil, sin embargo, también es el menos seguro. Básicamente elimina la posibilidad de permitir que los desarrolladores no confiables creen complementos porque esos complementos tendrán el mismo nivel de confianza que la aplicación host (lo que significa que si la aplicación host puede ejecutar métodos como System.IO.File.Delete
, también lo puede hacer el complemento)
Enfoque 2: ensamblado de plugin de MVC ejecutándose en el propio dominio de aplicación a través de MAF
Este enfoque tiene la intención de permitir la creación de plugins MVC que pueden ser incluidos en la zona de pruebas en sus propios AppDomains
y utilizados por el host a través de las bibliotecas System.Addin
.
Estructura
Se configura una ruta en el host que determina si la URL que se está procesando apunta a un complemento. Puede tener un patrón como
example.com/p/{plugin}/{controller}/{action}/{id}
Todas las rutas que tienen el patrón anterior se asignan a un controlador de host que tiene una acción de enrutamiento de módulo. Esa acción considera cualquier ruta determinada y determina el complemento adecuado para procesar la solicitud en función del segmento
{plugin}
.La vista del complemento es un objeto receptor / emisor que actúa como una puerta de enlace a los controladores del complemento. Tiene un método llamado AcceptRequest que recibe un
RequestContext
del host y que devuelve unActionResult
.La canalización del complemento contiene adaptadores que pueden serializar
RequestContext
yActionResult
para la transmisión a través del límite de aislamiento de la canalización.
Flujo de ejecución
Una ruta para un complemento coincide y se llama al controlador de enrutamiento del complemento.
El controlador carga el complemento requerido en su propio
AppDomain
y llama a AcceptRequest , pasando porRequestContext
(que se serializa a través de la canalización)AcceptRequest recibe el contexto y determina el controlador apropiado para ejecutar en función de esa solicitud (utilizando una fábrica de controladores personalizada).
Una vez que el controlador ha terminado de ejecutar la solicitud, devuelve un
ActionResult
al objeto receptor que luego pasa eseActionResult
(también serializado a través del pipeline) de regreso al hostAppDomain
.El controlador que inicialmente llamó a AcceptRequest puede devolver el
ActionResult
laActionResult
a laActionResult
de ejecución MVC del host, como si procesara la solicitud en sí. El pluginAppDomain
puede descargarse si así lo desea.
Ventajas
El complemento se incluirá en la zona de AppDomain
de su AppDomain
, por lo que se puede usar cualquier conjunto de permisos que se adapte al host.
Desventajas
- Tendría que ser posible serializar
RequestContext
yActionResult
. - Posiblemente romperá otra funcionalidad ASP.NET MVC dentro del
AppDomain
aislado.
Conclusión
Este enfoque suena bien en papel, pero no estoy seguro de si es posible / factible serializar los objetos RequestContext
y ActionResult
, así como ejecutar un controlador MVC de forma aislada.
Preguntas
El primer enfoque está bien si el código está siendo creado por desarrolladores de confianza. Sé que no voy a eliminar todos los archivos de la vista del host o su archivo web.config. Pero, en última instancia, si desea que los desarrolladores de terceros creen complementos para su aplicación MVC, debe ser capaz de protegerlos.
De toda mi investigación, la biblioteca System.Addin
hace que sea fácil implementar un entorno de host / plugin cuando se utilizan bibliotecas de clases basadas en API simples. Sin embargo, parece que no es fácil hacer esto cuando se trata de MVC.
Algunas preguntas que tengo son:
- ¿Es factible el segundo enfoque que he delineado aquí?
- ¿Hay una mejor manera de hacer esto?
- ¿Habrá formas más sencillas de lograr el aislamiento de plugins MVC en el futuro?
Vas a terminar creando sitios separados para cada complemento. De esta forma, puede crear usuarios de privilegios reducidos para cada AppPool y un administrador de sistemas puede instalar el "complemento" como un sitio web que se ejecuta bajo ese usuario.
Cualquier alternativa exhibirá el antipatrón de la plataforma interna. A menos que tenga mucho tiempo y dinero para gastar en el desarrollo de un sistema de alojamiento de plugins, se va a enredar en él y le molestará. Yo hablo por experiencia.
Los sitios pueden compartir los repos de usuarios de AspnetIdentity y puede proporcionar sus objetos centrales como un dll al que se puede hacer referencia. Aloje su contenido (archivos de script, CSS, imágenes) en un CDN para que puedan ser referenciados. Si desea compartir vistas con sus sitios secundarios, compílelos como recursos:
Inclusión de vistas compiladas previamente en una aplicación web ASP.NET MVC
¡Buena suerte!