2009-11-10 9 views
9

Tengo un desencadenante en el que deseo enviar un correo electrónico sobre las actualizaciones de una tabla en una tabla SalesClosing. Ahora el usuario (dbuser) que ejecuta el desencadenador tiene permisos muy limitados. Por lo tanto, quiero que el desencadenador se ejecute como dbmailuser. Un usuario que tiene derecho a enviar correos electrónicos. Probé que dbmailuser puede ejecutar sp_send_dbmail cuando inició sesión como ese usuario. Sin embargo, cuando el disparador se dispara, obtengo un error. No puedo ejecutar sp_send_dbmail. Así que inicié sesión como dbuser , ejecuté EXECUTE AS LOGIN = 'dbmailuser'; y fue capaz de ejecutar sp_send_dbmail. Ahora por qué no puedo hacer eso en un disparador. Estoy usando sql server 2008. A continuación se muestra el disparador ddl.servidor sql se ejecuta como un error de permiso en el desencadenador

alter TRIGGER SalesClosingTrigger ON SalesClosing 
WITH EXECUTE AS 'dbmailuser' 
for insert, update 
AS 
BEGIN 
    EXEC msdb.dbo.sp_send_dbmail 
    [email protected]_name = 'Test_Email_Profile', 
    @recipients='[email protected]', 
    @body = 'This is a test for Database Mail.', 
    @body_format = 'TEXT', 
    @subject = 'Database Mail Test' 
END 
GO 

Respuesta

14

Esto es debido a execute-as-user scoping - el cambio de contexto a un usuario a nivel de base de datos es por defecto de ámbito únicamente a la base de datos (y el código anterior se ejecuta fuera de la base de datos dada a través a msdb), y de sólo la base de datos la el autenticador no es válido Vea el enlace de arriba para obtener múltiples opciones sobre cómo resolver/solución de problemas.

+0

+1 no es todos los días ¡Conozco a alguien que entiende el contexto EXECUTE AS! –

+0

+1 Claro y justo en el punto –

10

El disparador es EXECUTE AS igual que EXECUTE AS USER = '...', no es lo mismo que EXECUTE AS LOGIN = '...'. chadhoc ya señaló el vínculo al contexto de suplantación EXECUTE AS y sus limitaciones. Básicamente, dado que la cláusula EXECUTE AS del desencadenador está garantizada por dbo, no por sysadmin, solo es confiable dentro del contexto de la base de datos.

hay dos alternativas:

  1. La talla única para todos mazo: ALTER DATABASE <yourdb> SET TRUSTWORTHY ON;. Esto elevará la marca de la base de datos como confiable y el contexto de ejecución puede ir fuera de la base de datos, si el inicio de sesión que posee la base de datos tiene los derechos propios. Esto no se recomienda en un entorno altamente seguro ya que abre las puertas a varias elevaciones de privilegios si no se restringe adecuadamente, y es muy difícil de restringir adecuadamente.

  2. La opción de precisión quirúrgica: firma de código. Ver Call a procedure in another database from an activated procedure para un ejemplo. Esto no es para corazones débiles, implica varios pasos complejos: generar un certificado, firmar el procedimiento, soltar la clave privada, copiar el certificado en msdb, crear un usuario derivado del certificado en msdb, otorgar autenticación de base de datos en el certificado usuario derivado, grante EJECUTAR en sp_send_mail en el usuario derivado del certificado. Cualquier error en cualquiera de estos pasos hará que toda la secuencia sea inútil, por lo que es muy fácil arruinarla, pero el resultado es absolutamente a prueba de balas desde el punto de vista de la seguridad.

+0

Remus, excelente información. Mantendré la firma del código en mente. Este servidor de base de datos es para una aplicación y solo tiene una base de datos. Simplemente no quería que el usuario principal tuviera acceso directo al sp_send_mail. Si alguien entra mucho en la base de datos, tengo más de qué preocuparse y luego enviar un correo electrónico. ¡Gracias de nuevo! – Josh

0

Enviar un correo electrónico desde un desencadenante es una mala idea. No desea poder realizar cambios en los datos si el servidor de correo electrónico no funciona.

Es mejor enviar la información para el correo electrónico a otra tabla que luego envía el correo electrónico de un trabajo que se ejecuta periódicamente. Uno que se ejecuta, digamos, cada cinco minutos.

También hay algo llamado Service Broker que no he usado antes que pueda ayudar en esta tarea, es posible que desee ver eso.

+1

En SQL 2005 y sp_send_dbmail ya utiliza Service Broker debajo de las cubiertas.Pone la solicitud de correo en una cola en msdb y un proceso externo la recoge, envía una confirmación y la entrega al servidor SMTP configurado. –

+1

Es una aplicación heredada, ASP clásico, etc. Las reglas tienen que doblarse/romperse para aplicaciones que no se ajustan a ningún estándar para empezar. – Josh

Cuestiones relacionadas