You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

SQL Server中WITH GRANT OPTION未生效,如何让TEST管理服务器触发器

问题描述

我拥有两个SQL Server登录账户OMEGACATEST,以及一个服务器级别的LOGON触发器:

CREATE TRIGGER [OMEGACA_ACC]
ON ALL SERVER WITH EXECUTE AS 'OMEGACA'
FOR LOGON
AS
    -- ...............

OMEGACA拥有publicsysadmin服务器角色,同时是数据库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

也可直接指定执行身份为OMEGACAWITH 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

火山引擎 最新活动