如何授权用户访问first schema对象,无需直接授予second schema权限?
问题:能否授权用户访问first schema对象,但不直接授予second schema权限?
我拥有两个schema:first和second。能否授权用户访问first schema中的对象(该对象内部调用了second schema的对象),而无需直接授予用户second schema的访问权限?
示例场景
first schema中的函数代码如下:
CREATE FUNCTION first.IsIdExists ( @Id int ) RETURNS bit AS BEGIN IF (EXISTS (SELECT * FROM second.GetIds AS i WHERE i.Id = @Id)) BEGIN RETURN 1; END RETURN 0; END
其中second.GetIds是second schema中的表。
若仅授予用户first schema的访问权限,执行该函数时会收到如下错误:
对数据库'testDb'中schema 'second'下的对象'GetIds'的SELECT权限被拒绝。
解决方案
可以通过以下两种方式实现需求,无需直接给用户授予second schema的权限:
1. 利用所有权链(推荐)
如果first和second两个schema的所有者相同(比如都属于dbo),SQL Server会自动启用所有权链机制:用户只要拥有first.IsIdExists的执行权限,就能间接访问second.GetIds,无需额外授权。
若两个schema所有者不同,可修改其中一个的所有者使其一致:
-- 假设first的所有者是dbo,将second的所有者也改为dbo ALTER SCHEMA second TRANSFER TO dbo;
之后给用户授予first schema的执行权限即可:
GRANT EXECUTE ON SCHEMA::first TO [目标用户名];
2. 使用EXECUTE AS子句定义函数
在创建函数时指定EXECUTE AS OWNER(或拥有second schema访问权限的特定用户),让函数以所有者身份执行,从而间接获取second.GetIds的访问权限:
CREATE FUNCTION first.IsIdExists ( @Id int ) RETURNS bit WITH EXECUTE AS OWNER -- 添加执行身份声明 AS BEGIN IF (EXISTS (SELECT * FROM second.GetIds AS i WHERE i.Id = @Id)) BEGIN RETURN 1; END RETURN 0; END
然后给用户授予该函数的执行权限:
GRANT EXECUTE ON first.IsIdExists TO [目标用户名];
注意:使用EXECUTE AS时需确保所有者确实拥有second.GetIds的访问权限,同时要警惕权限提升风险,避免过度授权。
内容的提问来源于stack exchange,提问作者VengeQ
相关产品推荐
相关产品推荐

