审计触发器中的当前事务ID

Chr*_*ers 10 t-sql sql-server

我正在考虑从审计触发器存储某种形式的事务id.解决方案似乎是使用sys.dm_tran_current_transaction,如本文后面的SQL Server触发器 - 按事务分组.

但是,我不能使用它,因为运行sql语句的用户帐户将不具有"查看服务器状态"权限并导致错误:

Msg 297, Level 16, State 1, Line 3
The user does not have permission to perform this action.

有没有人知道这个视图的替代方法,它将提供类似的事务ID或在触发器上使用"WITH EXECUTE AS"的方法,以允许从该视图中进行选择.

从我对"WITH EXECUTE AS"的尝试看来,服务器级权限似乎没有被转移,这是预期的,因为它模仿了数据库用户.

Rem*_*anu 13

您可以使用代码签名解决几乎所有安全问题.大多数细粒度和精细调整的访问控制,只是有点难以理解.

使用EXECUTE AS OWNER触发器,创建证书,签署触发器,删除私钥(以便其他任何人都无法使用它来再签署任何内容),导出证书(仅限公钥),在master中导入证书,创建登录从证书派生,授予对此登录的身份验证(为了将数据库扩展为模拟执行),然后将视图服务器状态授予此登录.这是防弹,完全控制的特权控制.如果需要更改触发器,则必须再次执行签名过程(包括证书派生登录和授权).从安全的角度来看,这是期望的(您正在签署触发器的特定变体),从操作的角度来看,它是一个皮塔饼,但是可以管理.

create table t (i int);
create table audit (transaction_id int);
go

create trigger t_audit_trigger
on t
with execute as owner
after insert, update, delete
as
begin
    set nocount on;
    insert into audit (transaction_id) 
    select transaction_id from sys.dm_tran_current_transaction;
    if (@@ROWCOUNT != 1)
        raiserror(N'Failed to audit transaction', 16, 1);
end
go

create certificate t_audit_view_server
    encryption by password = 'Password#123'
    with subject = N't_audit_view_server'
    , start_date = '08/10/2009';
go

add signature to t_audit_trigger
    by certificate t_audit_view_server
    with password = 'Password#123';
go

alter certificate t_audit_view_server
    remove private key;

backup certificate t_audit_view_server
    to file = 'c:\temp\t_audit_view_server.cer';
go

use master;
go

create certificate t_audit_view_server
    from file = 'c:\temp\t_audit_view_server.cer';
go  

create login t_audit_view_server_login
    from certificate t_audit_view_server;
go

grant authenticate server to t_audit_view_server_login;
grant view server state to t_audit_view_server_login;
go
Run Code Online (Sandbox Code Playgroud)