内联表值函数以“用户”身份执行
Posted
技术标签:
【中文标题】内联表值函数以“用户”身份执行【英文标题】:Inline-table valued function execute as 'user' 【发布时间】:2021-10-21 10:17:46 【问题描述】:是否可以作为某些用户执行内联表值函数? 例如
CREATE FUNCTION fun()
WITH EXECUTE AS owner
RETURN(
...
)
【问题讨论】:
它们被内联到外部查询中,因此在相同的执行上下文中运行。所以答案是“不” 请记住,内联表值函数的部分意义在于,它们被内联到更大的查询中,并作为整体的一部分进行了优化。这意味着查询的某些部分可能会被重写和移动。很难做到这一点和为关系运算符附加不同的权限。 是否有某些原因导致正常的所有权链接对您不起作用?如果func
引用的对象属于同一用户(例如dbo),则不检查函数引用的表的权限;对函数具有SELECT
权限的用户也不需要对表的权限。不需要EXECUTE AS
。
@DanGuzman 正常所有权有效。问题是该函数正在从另一个数据库调用对象,该特定用户不应该具有读取权限。在 MTVF 中可以“执行为”,但由于性能问题,这不是一个选项。
【参考方案1】:
来自EXECUTE AS Clause (Transact-SQL)的语法部分:
语法
-- SQL Server Syntax Functions (except inline table-valued functions), Stored Procedures, and DML Triggers EXEC | EXECUTE AS CALLER | SELF | OWNER | 'user_name'
所以不,你不能,内联表值函数明确表示为不能够定义WITH EXECUTE AS
选项。
【讨论】:
【参考方案2】:EXECUTE AS
不允许在答案和 cmets 中提到的 @Larnu 和 @MartinSmith 函数中使用。此外,即使允许,EXECUTE AS
安全上下文也会被沙箱化到当前数据库,除非您设置数据库 TRUSTWORTHY
,这是仅在绝对必要时才执行的操作。
所有权链接是EXECUTE AS
的替代方案。因为对象存在于其他数据库中,所以所涉及的数据库需要设置DB_CHAINING ON
选项并具有相同的所有者(假设 dbo 模式对象)。调用者需要被定义为所有涉及的数据库中的用户,但不需要对间接使用的对象授予对象权限。
只有在受信任的用户有权创建对象以避免特权提升时,才应启用 DB_CHAINING。
跨数据库链接的示例脚本:
ALTER DATABASE DB1 SET DB_CHAINING ON;
ALTER DATABASE DB2 SET DB_CHAINING ON;
GO
USE DB1;
GO
--user needs only SELECT on function
CREATE USER YourUser;
GRANT SELECT ON dbo.Fun TO YourUser;
GO
--user needs a security context in other database but no object permissions
USE DB2;
CREATE USER YourUser;
GO
【讨论】:
以上是关于内联表值函数以“用户”身份执行的主要内容,如果未能解决你的问题,请参考以下文章