Hace algunos meses trabajé con un cliente que estaba implementando una nueva versión de un portal Web de comercio electrónico. La aplicación, que utilizan principalmente sus socios comerciales, presenta datos de ventas y otros datos confidenciales. El cliente quería usar SQL Server Reporting Services, pero le preocupaban cuestiones de seguridad y la proliferación de informes. Específicamente, el cliente quería respuestas a dos cuestiones técnicas clave: cómo usar Reporting Services en un entorno en el que el mecanismo de autentificación de Windows no está disponible, y cómo instalar un conjunto común de informes para toda la aplicación, sin arriesgarse a que uno de los socios pudiera ver los datos de cualquier otro.
Debido a que estas cuestiones son comunes en entornos que instalan aplicaciones en Internet o extranets, voy a mostrarles como, primero, implementar un esquema de autentificación a medida para Reporting Services, y segundo, desarrollar informes que filtren datos y se ejecuten periódicamente según el usuario que desee verlos. También podrá usar esta técnica de filtrado con el modelo de seguridad por defecto de Reporting Services.
Autentificación y autorización
Primero repasemos rápidamente los conceptos de autentificación y de autorización. La autentificación es el proceso por el que se establece quiénes somos, mientras que la autorización es el proceso por el que se determina qué podemos o no hacer. Por ejemplo, cuando voy al gimnasio utilizo mi tarjeta de socio para establecer mi identidad (autentificación). Una vez dentro, tengo el privilegio de utilizar ciertas partes del club (por ejemplo, la pista de tenis o la piscina) en base a las autorizaciones que tengo concedidas. Por desgracia, muy pocas veces voy por el gimnasio.
Por defecto, Reporting Services 2005 utiliza el modo de autentificación de Windows para establecer identidades, y su propio conjunto de roles para conceder privilegios (a los que denomina Tareas) a usuarios o a grupos de usuarios de Windows. Este modelo de seguridad funciona bien para compañías que utilizan la autentificación de Windows en su organización. Sin embargo, cuando se trata de proporcionar informes fuera del cortafuegos de la empresa (o cuando ésta intenta integrarlo con un estándar de autentificación interno diferente), la autentificación de Windows a menudo no es una opción. Por suerte, el modelo de seguridad de Reporting Services es extensible (como muchas otras partes del producto). En este caso, la extensibilidad del producto permite reemplazar el modo de autentificación de Windows con un proveedor de autentificación personalizado. De manera más específica, un desarrollador puede implementar la interfaz de extensión de seguridad IAuthenticationExtension basada en .NET para que maneje las tareas de autentificación. Eso (entre otras cosas más) es lo que vamos a explicar en este artículo. (Para informarse sobre el uso de Web Services como solución alternativa, vea el recuadro adjunto “¿Y qué hay de los servicios Web?”).
Bases de la extensión de seguridad de Reporting Services
Reporting Services tiene sus fundamentos en .NET Framework y hace uso de una arquitectura modular diseñada con la extensibilidad en mente. Puede utilizar código .NET para extender varias áreas del producto, incluyendo las fuentes de informes de datos, la entrega, el procesamiento y la seguridad. Para usar un mecanismo de autentificación propio se implementa la interfaz de extensión de seguridad IAuthenticationExtension, de la misma forma que para personalizar el mecanismo de autorización se utiliza la interfaz IAuthorizationExtension.
Desde el punto de vista de la implementación, estas interfaces se compilan en forma de DLL. Se colocan dichas DLL en el directorio de Reporting Services y se modifica un conjunto de archivos de configuración de acuerdo con ello.
Reporting Services 2000 utilizaba ya esta arquitectura de extensión de seguridad, y no ha cambiado demasiado en la versión 2005. No obstante, Microsoft ha mejorado la documentación de la arquitectura, y ahora proporciona una extensión de seguridad de ejemplo. Puede encontrar una explicación detallada sobre las extensiones de seguridad en los Libros en pantalla de Microsoft SQL Server 2005, pero aquí le dejo un resumen acerca de las dos interfaces de extensión que implementaremos:
IAuthenticationExtension.
Esta interfaz representa a una extensión de autentificación, y contiene los siguientes tres métodos:
- GetUser –Devuelve la identidad del usuario. En un entorno de Internet, típicamente obtendríamos la identidad del usuario del contexto HTTP del servidor Web (por ejemplo, HTTPContext.Current.User.Identity).
- IsValidPrincipalName –Se llama cuando el servidor de informes establece la seguridad de un ítem. Configuramos este método para realizar peticiones a nuestro registro particular de usuarios.
- LogonUser –Utilizado para enviar credenciales al servidor de informes para la autentificación. Tras una petición exitosa, el servidor de informes utiliza cabeceras HTTP para otorgar un ticket de autentificación (esto es, una huella, o cookie) desde el servidor al cliente. El cliente usa entonces la huella en las peticiones subsiguientes durante el resto de la sesión. La Figura 1 muestra una representación gráfica de este proceso.
IAuthorizationExtension.
Esta interfaz maneja las autorizaciones a través de tres métodos:
- CheckAccess –Método que determina si un usuario tiene autorización para acceder a un ítem (por ejemplo, un informe) para una operación de catálogo determinada (por ejemplo, ExecuteReportDefinition). De hecho CheckAccess posee 10 firmas diferentes, de forma que para ahorrar tiempo, le recomiendo con especial énfasis el uso del código de ejemplo como punto de partida.
- CreateSecurityDescriptor –Usado para serializar la lista de códigos de acceso que se aplica a un ítem del servidor de informes. De forma parecida a una lista de control de acceso de Windows, la lista de códigos de acceso contiene los derechos de acceso que cada usuario tiene sobre los ítems de la base de datos de un servidor de informes en particular, como las carpetas o los informes individuales. CheckAccess utiliza este método.
- GetPermissions –Utilizado por el método GetPermissions del servicio Web, este método devuelve el conjunto de permisos concedidos a un usuario específico para un ítem dado.