触发器问题的权限

Kir*_*tor 6 schema trigger sql-server permissions sql-server-2008-r2

我正在使用 MS-SQL 2008 R2 中的数据库,但遇到了问题。

基本设置是这样的: 有两个感兴趣的表:dbo.Assesments 和 audit.Assesments。dbo.Assesments 是工作数据表,并具有数据更改(插入、更新、删除)触发器以更新带有更改日志的 audit.Assesments。据我所知,这已经工作了多年,到目前为止一切顺利。

我们的 L2 支持有一个名为 SupportRole 的角色,他们通过 WinAuth 进入该角色,并且该角色具有一些存储过程的选择权限和执行权限。其中一个存储过程会更新 dbo.Assesments。这就是问题所在:更新进入,存储过程触发以将审计行插入到 audit.Assesments,然后他们立即得到“插入被拒绝,插入权限不足”,事务角色返回等。

这让我很困惑:我曾认为触发器更像是存储过程,如果它们被创建,他们有权做任何他们正在做的事情,但这让我三思而后行。我不想为审计表/模式的支持角色授予插入权限。我该怎么办?

Han*_*non 9

默认情况下,触发器在导致触发器触发的主体的安全上下文下运行。

为了更改此行为,您需要使用WITH EXECUTE AS OWNER子句创建触发器。

下面是一个示例,展示了它是如何工作的。 WITH EXECUTE AS OWNER允许触发器在数据库所有者的安全上下文中运行,而不是在更新表的主体中运行。

首先,我们创建一个测试表:

USE tempdb;
IF OBJECT_ID('dbo.t') IS NOT NULL
BEGIN
    DROP TRIGGER t_trig;
    DROP TABLE dbo.t;
END
GO
CREATE TABLE dbo.t
(
    ID INT NOT NULL
    , ID2 INT NULL
);
GO
Run Code Online (Sandbox Code Playgroud)

这是触发器代码,带有EXECUTE AS OWNER

CREATE TRIGGER t_trig ON dbo.t
WITH EXECUTE AS OWNER
AFTER INSERT
AS
BEGIN
    UPDATE dbo.t
    SET ID2 = ID
    WHERE EXISTS (SELECT 1 FROM inserted i WHERE i.ID = dbo.t.ID);
END
GO
Run Code Online (Sandbox Code Playgroud)

现在,我们将创建一个具有低权限的测试登录,可用于测试EXECUTE AS OWNER允许低权限主体访问他们原本不会拥有的功能的假设:

CREATE LOGIN tLogin WITH PASSWORD = 'QWERFsdf23454%';
CREATE USER tLogin FROM LOGIN tLogin WITH DEFAULT_SCHEMA = dbo;
Run Code Online (Sandbox Code Playgroud)

我们将让他们能够将行插入到 中dbo.T,但阻止他们运行UPDATE语句:

GRANT INSERT ON dbo.t TO tLogin;
DENY UPDATE ON dbo.t TO tLogin;
Run Code Online (Sandbox Code Playgroud)

下面我们进行测试:

EXECUTE AS USER = 'tLogin';
/*
    Output here shows we're running under the tLogin
    security context
*/
SELECT SUSER_SNAME();
/* 
    This will fail, with insufficient privileges
    since we've DENY'd the UPDATE privilege to tLogin.
*/
UPDATE dbo.t SET ID2 = ID; 
/*
    this will run the UPDATE since the trigger 
    has EXECUTE AS OWNER
*/
INSERT INTO dbo.t(ID) VALUES (1); 
/*
    This takes us out of the tLogin security context
*/
REVERT
Run Code Online (Sandbox Code Playgroud)

在这里我们可以看到行中dbo.T有触发器所做的更改:

SELECT *
FROM dbo.t;
Run Code Online (Sandbox Code Playgroud)

在这里,我们清理低权限用户:

DROP USER tLogin;
DROP LOGIN tLogin;
Run Code Online (Sandbox Code Playgroud)

运行上面的输出是:

在此处输入图片说明