You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL Server 2016中EXECUTE AS SELF与跨数据库视图的权限异常问题

为啥会出现这个问题?

当你用EXECUTE AS SELF创建存储过程dbo.f时,这个存储过程会以创建它的你的身份来执行。虽然你直接查询TheView没问题,但这里的核心坑在于:SQL Server默认不允许跨数据库的权限链自动传递——哪怕你是B库的dbo,在A库的存储过程上下文里访问B库的表时,权限校验会因为跨库上下文的切换而失败,导致你看到的权限不足类错误。

解决办法来啦(按安全优先级排序)

1. 开启跨库所有权链(最推荐)

如果TheView(A库的dbo所有)和SomeTable(B库的dbo所有)的所有者一致(都是dbo),你可以给两个数据库开启DB_CHAINING属性,这样跨库的所有权链就能生效,存储过程执行时就不会卡在权限校验上了:

-- 给数据库A开启跨库所有权链
ALTER DATABASE A SET DB_CHAINING ON;
GO
-- 给数据库B开启跨库所有权链
ALTER DATABASE B SET DB_CHAINING ON;
GO

执行完这两句后,再运行dbo.f应该就能正常返回结果了。

2. 把EXECUTE AS改成OWNER

如果你的存储过程所有者是A库的dbo,且这个dbo对应的登录账号在B库也拥有dbo权限,那可以把存储过程的执行上下文换成OWNER

USE A;
GO
ALTER PROC dbo.f WITH EXECUTE AS OWNER
AS
SELECT * FROM TheView;
GO

EXECUTE AS OWNER会以存储过程所有者的身份执行,跨库访问同所有者的对象时,权限传递会更顺畅。

3. 谨慎开启TRUSTWORTHY(不推荐,有安全风险)

如果上面两种方法都不适用,你可以尝试开启A库的TRUSTWORTHY属性,但必须注意:这会让A库的所有者获得服务器级别的权限,存在不小的安全隐患,非必要情况下不建议使用:

ALTER DATABASE A SET TRUSTWORTHY ON;
GO

内容的提问来源于stack exchange,提问作者Seva Alekseyev

火山引擎 最新活动