Vous êtes sur la page 1sur 7

Construccin de un sistema de Triggers en Microsoft SQL Server. Por Mariano Minoli.

auditora con Introduccin La auditoria de sistemas es un punto importante a considerar en sistemas cliente /servidor en los cuales existe una multitud de usuarios trabajando sobre una mis ma fuente de datos. Cuando dichos sistemas son de pequeo porte y poseen pocos usu arios el problema podra parecer trivial, pero a medida que la envergadura del sis tema crece y (sobre todo) la cantidad y variedad de usuarios es mayor, la audito ria se convierte en un punto difcil de manejar. En este artculo se intenta present ar dos soluciones posibles al problema y desarrollar una de ellas en la cual sol o se utiliza Transact-SQL, por ltimo se darn las bases para automatizar la instala cin de la solucin presentada y algunas consideraciones y optimizaciones posibles. Sobre auditora Antes que nada habra que aclarar a que nos referimos cuando hablamo s de "auditoria". En este mbito, con auditoria nos referimos al seguimiento de la s operaciones realizadas por cada usuario, bsicamente llevar un control de "que s e hace", "quien lo hace (el Usuario)", "en donde se hace", y "cuando se hace". E l concepto no es nuevo, en los entornos mainframe suele ser llamado "el login de l sistema", aquel lector que est relacionado con la jerga entender que nos referim os a lo mismo, solo diferimos en la forma de implementarlo. Tambin podra hallarse una cierta analoga con los eventos visualizados en la seccin de Seguridad del Viso r de Eventos de Windows NT/2000. Diferentes enfoques para un mismo problema Prim ero buscaremos donde almacenar la informacin, mas all de cmo hacerlo. Puede que el lector est pensando en una tabla en la cual se almacenen datos que contesten a la s preguntas hechas en el prrafo anterior, no vamos a contradecirlo: las dos soluc iones propuestas incluyen una tabla almacenada en la base de datos. El formato d e la tabla puede variar dependiendo de las necesidades especficas del entorno, no sotros proponemos la siguiente, a los efectos del desarrollo: El script para la creacin de la tabla es: CREATE TABLE [dbo].[AUDIT] ( [id_evento ] [int] IDENTITY (1, 1) NOT NULL , [tipo_evento] [char] (10) NOT NULL , [fecha] [datetime] NOT NULL , [descripcion] [char] (50) NULL , 1

[usuario] [char] (30) NULL , [terminal] [char] (30) NULL , [aplicacion] [char] ( 30) NULL) ON [PRIMARY]GOALTER TABLE [dbo].[AUDIT] WITH NOCHECK ADD CONSTRAINT [P K_AUDIT] PRIMARY KEY NONCLUSTERED ( [id_evento] ) ON [PRIMARY] GO Ahora que sabe mos dnde vamos a almacenar la informacin, necesitamos determinar cmo vamos a hacerl o. Presentamos dos opciones: 1. Delegar la responsabilidad en la lgica de negocio de la aplicacin. 2. Crear dis paradores en cada tabla que se desee auditar. 1er opcin: Delegar la responsabilidad en la lgica de negocio de la aplicacin. Con e sto nos referimos a que dentro del cdigo encargado de hacer modificaciones a los datos, se realicen las inserciones a la tabla AUDIT, de este modo, cualquier ope racin generar un registro de auditoria. La ubicacin del cdigo (responsable de las in serciones) depender de la arquitectura que utilice el desarrollador, ya sea en un a arquitectura de dos o tres capas, en donde se concentre la lgica de negocio de la aplicacin, all estar el cdigo encargado de realizar las inserciones de auditora. 2 da opcin: Crear disparadores en cada tabla que se desee auditar. De este modo, cada tabla (que se desee auditar) tendr un disparador (o trigger) q ue, cada vez que detecte una modificacin en la tabla, inserte un registro en la t abla de auditora. Si el lector desconoce el concepto de disparador, en las seccio nes siguientes describiremos en detalle de que se trata, por ahora vemoslo como " algo" que est "latente" en la base de datos que, al detectar una modificacin en lo s datos de una determinada tabla, ejecuta una serie de sentencias Transact-SQL p reviamente configuradas. La opcin que se va a desarrollar es la segunda, la decis in no es arbitraria, obedece a una serie de ventajas que se detallan a continuacin : Primero que nada, el hecho de descargar lgica del lado del cliente suele ser PE LIGROSO, en este caso las aplicaciones se hacen ms complejas de programar y mante ner. Si se usan disparadores como solucin se est reutilizando cdigo implcitamente, c ualquier nueva aplicacin que acceda a una tabla existente, ser "automticamente" aud itada sin necesidad de escribir una sola lnea de cdigo de ms. Adems, hay que tener e n cuenta que si el sistema es accedido a travs de Webforms (ASP.Net) no ser bueno cargar al cliente de trabajo que se debera concentrar del lado del servidor. Por l timo, como hemos dicho antes, es posible que existan "mltiples usuarios" accedien do de "mltiples maneras" al gestor. Muchas de estas "maneras" pueden no ser aplic aciones propietarias, un usuario por ejemplo podra acceder a travs del Query Analy zer y ejecutar una sentencia delete a una tabla cualquiera, si la auditoria se e ncuentra en el cliente que hemos programado, nunca sabremos quien fue. El lector debe tener en cuenta que NO existe manera de modificar datos en una base de dat os SQL Server y evitar que se ejecuten los disparadores que estn asociados a esto s datos. Conceptos tericos y construcciones utilizadas Para poder comprender corr ectamente las secciones siguientes, es necesario tener claros algunos conceptos de teora de bases de datos y la sintaxis de algunas sentencias: Desencadenador (t rigger) 2

Podra definirse como un tipo especial de procedimiento almacenado que se ejecuta automticamente cuando un usuario intenta modificar datos sobre una tabla determin ada. Los disparadores se almacenan en la base de datos en forma similar a los pr ocedimientos almacenados, sin embargo NUNCA son ejecutados explcitamente por los usuarios, slo se disparan cuando el gestor detecta una modificacin. Existen tres t ipos de disparadores, uno para cada tipo de actualizacin: Eliminacin Insercin Modif icacin La sintaxis que utilizaremos durante este desarrollo para la creacin de dis paradores es la siguiente: CREATE TRIGGER nombre_trigger ON tabla [WITH ENCRYPTI ON] { {FOR { [DELETE] [,] [INSERT] [,] [UPDATE] } AS sentencia_sql [...n]} Cabe aclarar que existen otras opciones adicionales que no son utilizadas durante est e desarrollo. Sentencia insert utilizada con un select Debido a que no es la sin taxis ms popular de un insert, nos pareci interesante explicarle que se va a utili zar la clusula de la siguiente manera: Insert into TABLA _ DESTINO Select * from TABLA _ ORIGEN Esta sentencia inserta todos los registros obtenidos como el resu ltado de la consulta a la TABLA_ORIGEN en la TABLA_DESTINO Execute Puede ser uti lizado para ejecutar un procedimiento almacenado o (como en nuestro caso) para e jecutar un conjunto de sentencias Transact-SQL que es pasada como un string, est o nos permite "armar" la sentencia concatenando partes fijas con variables que v an tomando distintos valores. Las funciones getdate(), host_name(), SYSTEM_USER, APP_NAME Usamos estas funciones para "capturar" valores que nos interesa almace nar en la tabla AUDIT. Sus significados son: Getdate(): Fecha-hora actual del si stema. SYSTEM_USER: Nombre del usuario que enva una sentencia al servidor. host_n ame(): Nombre de la maquina cliente desde donde se enva la sentencia. APP_NAME: N ombre de la aplicacin cliente a travs de la cual se enva la sentencia. Desarrollo C on lo que se ha explicado hasta el momento, poco nos resta para implementar el s istema de auditoria, simplemente hay que crear un disparador por cada tabla que se quiera auditar, el disparador tiene que ejecutar un insert a la tabla AUDIT, vemoslo con un ejemplo. Supongamos una tabla CLIENTES, que presenta la siguiente estructura (muy simplificada, solo para fines demostrativos): La sentencia de cr eacin de esta tabla es: CREATE TABLE [dbo].[CLIENTES] ( [id_cliente] [int] NOT NU LL , 3

[Nombre] [char] (50) NOT NULL) ON [PRIMARY] GO Para esta tabla las sentencias de creacin de los disparadores son las siguientes: CREATE TRIGGER AUDITdel ON CLIEN TES FOR DELETE AS Insert into AUDIT select "Delete", getdate(), "Eliminacion de un registro", SYSTEM_USER, host_name(),APP_NAME() CREATE TRIGGER AUDITins ON CLI ENTES FOR INSERT AS insert into AUDITselect "Insert", getdate(), "Insercion de u n registro", SYSTEM_USER, host_name(),APP_NAME() CREATE TRIGGER AUDITdel ON CLIE NTES FOR UPDATE AS insert into AUDITselect "Update", getdate(), "Modificacion de un registro", SYSTEM_USER, host_name(),APP_NAME() Cabe aclarar que lo mismo se podra hacer de una manera ms "amigable" desde el Administrador Corporativo (Enterp rise Manager). Habiendo creado los tres disparadores sobre la tabla clientes, in tente hacer cualquier operacin que modifique los datos de la misma, por ejemplo p odra ejecutar las tres sentencias siguientes: Insert into CLIENTES values (2356, "Juan Perez") Go Update CLIENTES set Nombre = "Ricardo Perez" where id_cliente = 2356 Go Delete CLIENTES where id_cliente = 2356 Si analiza la tabla AUDIT ver qu e las sentencias ejecutadas accionaron los disparadores que se haban creado. stos insertaron un registro por cada modificacin efectuada a la tabla. Verifique con l a siguiente consulta: select * from AUDIT Optimizacin 1: Creacin de un Procedimien to Almacenado que automatice la instalacin del sistema Con lo visto hasta el mome nto, ya esta en condiciones de crear sus propios disparadores sobre cada tabla q ue desee auditar, ahora suponga que quiere auditar con este mtodo la base de dato s corporativa, en la cual se alojan datos referentes a todos los subsistemas de la organizacin. Suponga que las tablas a auditar son 300. No le interesa la idea d e automatizar la instalacin de los disparadores? Lo que se presenta a continuacin es un procedimiento almacenado que encapsula la creacin de los tres disparadores para una tabla determinada que es pasada como parmetro de entrada: CREATE PROCEDU RE sp_instalarTrigger @tabla as char(128) as -- Aseguramos que el parametro de e ntrada est libre de espacios set @tabla = ltrim(rtrim(@tabla)) 4

-- Creacion del trigger para ELIMINACION EXECUTE ('CREATE TRIGGER AUDITdel_' + @ tabla +' ON ' + @tabla +' FOR DELETE AS Insert into AUDITselect "Delete", getdat e(), "Eliminacion de un registro", SYSTEM_USER, host_name(),APP_NAME()') -- Crea cion del trigger para INSERCION EXECUTE ('CREATE TRIGGER AUDITins_' + @tabla +' ON ' + @tabla +' FOR INSERT AS Insert into AUDITselect "Insert", getdate(), "Ins ercion de un registro", SYSTEM_USER, host_name(),APP_NAME()') -- Creacion del tr igger para MODIFICACION EXECUTE ('CREATE TRIGGER AUDITupd_' + @tabla +' ON ' + @ tabla +' FOR UPDATE AS Insert into AUDITselect "Update", getdate(), "Modificacio n de un registro", SYSTEM_USER, host_name(),APP_NAME()') Por ejemplo, para nuest ra tabla sera: Exec sp_instalarTrigger "CLIENTES" Un segundo paso para lograr una instalacin totalmente automtica podra ser crear otro procedimiento almacenado que: Cargue un cursor con todas las tablas de usuario a travs de un select de la tabl a sysobjects (con la condicin de que el campo xtype sea "U"). Luego ejecute el pr ocedimiento almacenado antes creado por cada registro dentro del cursor. Sin emb argo debe ser cuidadoso con este enfoque de "instalacin masiva" porque la sobreca rga de procesamiento que existir en el servidor a partir de la instalacin de los d isparadores podra no ser aceptable (o deseable) en todas la tablas, mas adelante hablaremos de ello. Optimizacin 2: Personalizacin del mensaje grabado (tablas inse rted y deleted)Si analiza la tabla AUDIT que se ha propuesto ver que uno de los c ampos es "descripcin". Hasta el momento hemos estado insertando una cadena fija q ue presenta una suerte de descripcin acerca del evento que dispara el disparador, en realidad ese campo est pensado para guardar una descripcin detallada del event o ocurrido, cun detallada?, todo lo detallada que el usuario considere necesario y est dispuesto a programar. A continuacin desarrollamos un ejemplo prctico para el disparador que controla la eliminacin, en donde utilizamos la tabla "deleted", sta es una tabla temporal a la cual se puede tener acceso dentro de un disparador, de este modo podemos recuperar los datos que estn siendo eliminados y que han dis parado la ejecucin del disparador (ntese que tambin se podra utilizar la tabla tempo ral inserted accesible desde los disparadores para insercin). Lo que vamos a hace r es recuperar el nombre del cliente que se est eliminando y lo vamos a guardar e n el campo descripcin de la tabla AUDIT. De este modo reformulamos la creacin del disparador de la siguiente manera: -- Primero eliminamos el trigger que se habia creado anteriormente if exists (select * from sysobjects where id =object_id(N' [dbo].[AUDITdel_CLIENTES]') and OBJECTPROPERTY(id, N'IsTrigger') = 1) drop trigg er [dbo].[AUDITdel_CLIENTES] GO -- Luego creamos el trigger para ELIMINACION con el mensaje personalizado 5

CREATE TRIGGER AUDITdel_CLIENTES ON CLIENTES FOR DELETE AS Insert into AUDIT sel ect "Delete",getdate(), (select "Nombre eliminado: " + convert(char(15),Nombre) from deleted) ,SYSTEM_USER, host_name(),APP_NAME() Con este enfoque se podran alm acenar todos los datos antes de una eliminacin para poder reconstruir un registro si es necesario, aunque si su aplicacin hace eliminaciones masivas (es decir de mas de dos registros), debera replantear la insercin a la tabla AUDIT recorriendo, por ejemplo, un cursor armado con una consulta a la tabla deleted.Aqu cabe una a claracin: el cdigo Transact-SQL que se encuentra dentro del trigger puede estar co mpuesto por bucles, condicionales, casi cualquier construccin Transact-SQL vlida, sin embargo deber tener en cuenta que toda la demora que introduzca este cdigo imp actar directamente en cada una de las operaciones que los usuarios hagan sobre lo s datos. Encriptacin de los disparadores Una consideracin que podra ser importante es la de encriptar el cdigo de los disparadores creados, de este modo evitar que s e conozca cmo y dnde se est almacenando la informacin de auditora, ms all de que luego restrinja el acceso a la tabla AUDIT. El cdigo debe ser encriptado al momento de la creacin del disparador a travs de la clusula "WITH ENCRYPTION", para nuestro dis parador de eliminacin sera: -- Primero eliminamos el trigger que se haba creado ant eriormente if exists (select * from sysobjects where id =object_id(N'[dbo].[AUDI Tdel_CLIENTES]') and OBJECTPROPERTY(id, N'IsTrigger') = 1)drop trigger [dbo].[AU DITdel_CLIENTES] GO -- Luego creamos el trigger para ELIMINACION con el mensaje personalizado y ENCRIPTADO CREATE TRIGGER AUDITdel_CLIENTES WITH ENCRYPTION ON C LIENTES FOR DELETE AS Insert into AUDIT select "Delete",Getdate(), (select "Nomb re eliminado: " + convert(char(15),Nombre) from deleted), SYSTEM_USER, host_name (),APP_NAME() Conclusiones Hemos visto como, a partir de unas simples sentencias de Transact-SQL, se puede crear todo un sistema que realice un seguimiento muy detallado de las operaciones de los usuarios sobre los datos. Adems vimos que su diseo es flexible y puede ser personalizado para necesidades especficas. Si desea, puede completar el desarrollo creando una interfaz grfica que acceda a la tabla AUDIT y permita hacer consultas con filtros configurables por el usuario, emitir reportes, etc. 6

Vous aimerez peut-être aussi