Usar COM Interop Office (Excel) en tus proyectos ASP.NET y no morir en el intento...


En el proyecto en el que me encuentro, tenemos desarrollada una librería .NET para obtener informes en Excel mediante la llamada a una BAPI de SAP. Esta librería trabaja con el objeto COM de Excel y al mismo tiempo es consumida desde ASP.NET, sí, ya se que Microsoft no recomienda el uso de componentes Office en aplicaciones ASP.NET, "COM Interop with Microsoft Office products from an ASP.NET web page. Excel was not designed to be used inthis way" pero esto es un caso de fuerza mayor y no hay mas narices, puesto que son informes bastantes complejos que no basta con utilizar un DataGrid y rendereizar su contenido y lanzar una salida con Response.Write y poner el Response.ContentType = "application/vnd.ms-excel, como tantos ejemplos hay por ahí.
El problema con el que me he encontrado es el siguiente:
Todas las pruebas realizadas han funcionado a la perfección en las máquinas de desarrollo (Eso de ser Administrador de máquina...) pero... cuando lo he montado en el servidor de pruebas y he hecho la primera petición de un informe me he encontrado con esto:
Acceso Denegado
Juer, pues si que empezamos bien. La primera conclusión es evidente: Falta de Permisos, así que le he arrancado el Debugger de mi máquina y le he pedido a mi compañero que hiciera una petición de informe para ver donde casca:
ApplicationClass objExcel = new ApplicationClass();
Le he dado permisos de Administrador a mi compañero en mi máquina, ha vuelto a ejecutar la petición y ¡Vualá! todo funciona, porque estas llamadas a objetos COM necesitan para ejecución local/remota unos privilegios mínimos.
La configuración del sitio web tiene el acceso anónimo deshabilitado y la autenticación windows integrada (Estamos en una intranet) y en el Web.Config impersonate a true con autenticación Windows.
Soluciones que no piensas:
  • Dar permisos de Adminsitrador a la cuenta MACHINE\ASPNET
ESTO NI SE TE OCURRA
  • Impersonar el hilo de ejecución de la aplicación con un usuario Adminsitrador
La gente de sistemas nunca te lo dará y además no me parece una buena solución puesto que vulnera muchos principios de seguridad como en el primer caso.
  • Hacer una impersonación sólo cuando generas el Informe con una cuenta de usuario que sea Adminsitrador 
La gente de sistemas nunca te lo dará
Bueno, pues visto que esto va a ser que no, de repente, cacharreando con los Servicios de Componentes encuentro una cosita que se llamaConfiguración DCOM (Distributted Component Object Model) y al expandirlo me encuanto con esto:
Síííííí!!!! Aplicación Microsoft Excel, esto pinta bien y además tiene propiedades, así que pinchamos:
Juer y encima tiene una pestaña de Seguridad
Así que marcamos el check Personalizar de los Permisos de inicio y activación y pulsamos el botón Modificar para dar permisos al Usuario/Grupo que desamos:
Aceptamos todo y con esto hemos resuelto el maldito error. En mi caso hemos dados permisos a un Grupo que contiene a los usuarios que acceden a la aplicación. (Aunque la imagen corresponde al equipo mio de casa ;))
Por último y por cuestiones de performance en nuestra aplicación es necesario liberar todos los objetos COM que utilicemos, para que no se queden esos malditos procesos llamados EXCEL (Os lo digo por experiencia propia), que aperecen a porrillo en el Administrador de Tareas, y para ello os dejo este enlace del Support de Microsoft:
Con la solución que propone conseguí eliminar eso malditos procesos que parecían desaparecer con el oApp.Quit(); oApp = null; pero que en realidad no desaparecían y se estaban acumulando llevandose 36 Mb de memoria cada uno.
Bueno pues espero que os sirva y que no tengáis que romperos tanto el coco y os encontréis tantos probelmas como me he encontrado yo.

No hay comentarios:

Publicar un comentario