DDL触发器用于登录将数据插入表中

时间:2013-10-28 13:33:00

标签: sql-server sql-server-2008 security sql-server-2008-r2 ddl-trigger

我的服务器上有一个下面的DDL触发器

CREATE TRIGGER [DDLForLogin] ON ALL SERVER
FOR LOGON 
AS BEGIN
    DECLARE @data XML
    SET @data = EVENTDATA()

    IF EXISTS(SELECT * FROM sys.Databases WHERE NAME = 'DatabaseMaintenance') Begin
        INSERT INTO DatabaseMaintenance.dbo.MyTable (UserName, HostName, ApplicationName, EventDataValue)
        VALUES (CURRENT_USER, HOST_Name(), APP_NAME(),@Data)
    END  
END;

登录为Windows Authentication在MyTable上插入一行,但登录为SQL Server Authentication时出现错误:

Logon failed for login 'xxx' due to trigger execution.
Changed database context to 'master'.
Changed language setting to us_english. (Microsofr SQL Server, Error: 17892)

修改

GRANT INSERT在我的桌子上PUBLIC

但对引发的错误没有任何改变。

EDIT2

我更改触发器并在触发器上添加With Execute AS 'sa'

但对引发的错误没有任何改变。

2 个答案:

答案 0 :(得分:0)

尝试向EXECUTE AS添加适当的trigger子句 - 默认为CALLER,因此,除非 用户有权插入审核表< sup> 1 ,触发器将失败。

此外,然后在触发器中使用ORIGINAL_LOGIN()来获取正确的登录信息

1 您通常不想要的 - 因为否则每个用户都可以伪造其他用户已登录的条目。

答案 1 :(得分:0)

必须将触发器更改为以下代码:

CREATE TRIGGER [DDLForLogin] ON ALL SERVER
WITH EXECUTE AS 'sa'
FOR LOGON 
AS BEGIN
    DECLARE @data XML
    SET @data = EVENTDATA()

    DECLARE @IsPooled int
    SET @IsPooled = @data.value('(/EVENT_INSTANCE/IsPooled)[1]', 'int')

    IF EXISTS(SELECT * FROM sys.Databases WHERE NAME = 'DatabaseMaintenance')AND (@IsPooled=0) Begin
        insert into DatabaseMaintenance.dbo.Login (UserName, HostName, ApplicationName, EventDataValue)
        values (ORIGINAL_LOGIN(), HOST_Name(), APP_NAME(),@Data)
    END
END;