SQL Server中WITH GRANT OPTION未生效,如何让TEST管理服务器触发器
我拥有两个SQL Server登录账户OMEGACA和TEST,以及一个服务器级别的LOGON触发器:
CREATE TRIGGER [OMEGACA_ACC] ON ALL SERVER WITH EXECUTE AS 'OMEGACA' FOR LOGON AS -- ...............
OMEGACA拥有public和sysadmin服务器角色,同时是数据库OmegaCoreAudit的所有者。在该数据库中,我创建了OMEGACA架构及用于启用/禁用OMEGACA_ACC触发器的存储过程:
USE [OmegaCoreAudit] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [OMEGACA].[P_SYS_MANAGE_ACC] (@p_trigger_status int) AS BEGIN SET NOCOUNT ON; -- Check Trigger Status IF @p_trigger_status = 0 BEGIN DISABLE TRIGGER OMEGACA_ACC ON ALL SERVER; END ELSE IF @p_trigger_status = 1 BEGIN ENABLE TRIGGER OMEGACA_ACC ON ALL SERVER; END ELSE BEGIN RAISERROR('Wrong status 1/0 value !', 16, 1); END; END;
我希望TEST登录账户能够执行该存储过程来启用/禁用服务器触发器,但不想直接为其授予CONTROL SERVER权限。我已执行以下操作:
- 为
OMEGACA登录账户授予带WITH GRANT选项的CONTROL SERVER权限; - 将
TEST登录账户映射到OmegaCoreAudit数据库的TEST用户; - 为
TEST用户授予[OMEGACA].[P_SYS_MANAGE_ACC]的EXECUTE权限。
但当以TEST身份执行该存储过程时:
USE [OmegaCoreAudit] GO DECLARE @RC int -- TODO: Set parameter values here. EXECUTE @RC = [OMEGACA].[P_SYS_MANAGE_ACC] 0 GO
出现错误:
Msg 1088, Level 16, State 120, Procedure OMEGACA.P_SYS_MANAGE_ACC, Line 21 [Batch Start Line 2]
Cannot find the object "OMEGACA_ACC" because it does not exist or you do not have permissions.
请问如何让TEST登录账户正确执行该存储过程?
错误核心原因:默认情况下存储过程以调用者(TEST用户)的权限执行,而TEST用户没有服务器级别的权限操作服务器触发器。即使触发器本身设置了EXECUTE AS 'OMEGACA',存储过程的执行上下文也不会继承该权限。
解决步骤如下:
1. 修改存储过程,指定执行上下文
添加WITH EXECUTE AS OWNER,让存储过程以数据库所有者(OMEGACA)的身份运行——OMEGACA作为sysadmin角色成员,拥有操作服务器触发器的权限:
USE [OmegaCoreAudit] GO ALTER PROCEDURE [OMEGACA].[P_SYS_MANAGE_ACC] (@p_trigger_status int) WITH EXECUTE AS OWNER -- 新增执行上下文设置 AS BEGIN SET NOCOUNT ON; -- Check Trigger Status IF @p_trigger_status = 0 BEGIN DISABLE TRIGGER OMEGACA_ACC ON ALL SERVER; END ELSE IF @p_trigger_status = 1 BEGIN ENABLE TRIGGER OMEGACA_ACC ON ALL SERVER; END ELSE BEGIN RAISERROR('Wrong status 1/0 value !', 16, 1); END; END; GO
也可直接指定执行身份为OMEGACA:WITH EXECUTE AS 'OMEGACA',但使用OWNER更灵活,后续若数据库所有者变更无需修改存储过程。
2. 确认TEST用户的EXECUTE权限
若之前的授权已生效可跳过此步;若不确定,重新执行授权语句:
USE [OmegaCoreAudit] GO GRANT EXECUTE ON [OMEGACA].[P_SYS_MANAGE_ACC] TO [TEST]; GO
完成以上操作后,TEST用户即可正常执行该存储过程管理服务器触发器,且无需直接拥有CONTROL SERVER权限。
内容的提问来源于stack exchange,提问作者altink




