2009-11-10 9 views
9

Ho un trigger in cui voglio inviare un'e-mail sugli aggiornamenti di una riga in una tabella SalesClosing. Ora l'utente (dbuser) che esegue il trigger ha autorizzazioni molto limitate. Quindi voglio che il trigger venga eseguito come dbmailuser. Un utente che ha i diritti per inviare email. Ho verificato che dbmailuser può eseguire sp_send_dbmail dopo aver effettuato l'accesso come tale utente. Tuttavia, quando il trigger si attiva, viene visualizzato un errore che non è possibile eseguire sp_send_dbmail. Così ho effettuato il login come dbuser , eseguito EXECUTE AS LOGIN = 'dbmailuser'; ed è stato in grado di eseguire sp_send_dbmail. Ora, perché non posso farlo in un trigger. Sto usando SQL Server 2008. Di seguito è il trigger ddl.sql viene eseguito come errore di autorizzazione nel trigger

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 

risposta

14

Ciò è dovuto execute-as-user scoping - contesto passaggio a un livello di utente database è predefinita ambito solo quel database (e il codice precedente viene esecuzione di fuori del database data indietro per msdb), e il database di sola autenticatore non valido. Vedi il link sopra per più opzioni su come risolvere/aggirare.

+0

+1 non è ogni giorno che incontro qualcuno che capisca il contesto ESEGUI! –

+0

+1 Cancella e destra nel punto –

10

EXECUTE AS dei trigger è uguale a EXECUTE AS USER = '...', non uguale a EXECUTE AS LOGIN = '...'. chadhoc ha già indicato il collegamento al contesto di rappresentazione di EXECUTE AS e ai suoi vincoli. Fondamentalmente, poiché la clausola EXECUTE AS del trigger è garantita da dbo, non da sysadmin, è affidabile solo all'interno del contesto del database.

ci sono due alternative:

  1. La taglia unica mazza: ALTER DATABASE <yourdb> SET TRUSTWORTHY ON;. Ciò consentirà di contrassegnare il database come attendibile e il contesto di esecuzione può andare all'esterno del database, se il database proprietario del database dispone dei diritti di sospensione. Questo non è raccomandato in un ambiente altamente protetto in quanto apre le porte a vari livelli di privilegi se non è adeguatamente vincolato ed è molto difficile vincolare correttamente.

  2. L'opzione di intervento chirurgico: firma del codice. Vedere Call a procedure in another database from an activated procedure per un esempio. Questo non è per i deboli di cuore, coinvolge diversi passaggi complessi: generare un certificato, firmare la procedura, rilasciare la chiave privata, copiare il certificato in msdb, creare un utente derivato dal certificato in msdb, concedere il database di autenticazione sul certificato utente derivato, grante EXECUTE su sp_send_mail sull'utente derivato dal certificato. Qualsiasi errore in uno di questi passaggi renderà inutile l'intera sequenza, quindi è molto facile rovinarlo, ma il risultato è assolutamente a prova di proiettile dal punto di vista della sicurezza.

+0

Remus, informazioni eccellenti. Terrò a mente la firma del codice. Questo server database è per un'applicazione e ha un solo database. Non volevo che l'utente principale avesse accesso diretto a sp_send_mail. Se qualcuno entra nel database per molto, ho più di cui preoccuparmi, quindi inviare email. Grazie ancora! – Josh

0

L'invio di un'e-mail da un trigger è una cattiva idea. Non si desidera essere in grado di apportare modifiche ai dati se il server di posta elettronica non è attivo.

È meglio inviare le informazioni per l'e-mail a un'altra tabella che quindi invia l'e-mail da un lavoro periodicamente in esecuzione. Uno che viene eseguito ogni cinque minuti.

C'è anche qualcosa chiamato Service Broker che non ho usato prima che possa aiutare in questa attività, potreste volerlo vedere.

+1

In SQL 2005 e su sp_send_dbmail utilizza già Service Broker sotto le copertine.Mette la richiesta di posta in una coda in msdb e un processo esterno la preleva, la registra e la consegna al server SMTP configurato. –

+1

È un'app legacy, classica asp ecc. Le regole devono essere piegate/spezzate per le app che non sono conformi agli standard per iniziare. – Josh

Problemi correlati