内联表值函数以“用户”身份执行

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

【讨论】:

以上是关于内联表值函数以“用户”身份执行的主要内容,如果未能解决你的问题,请参考以下文章

SQL 中内联表值函数的性能影响

内联表值函数中 SELECT * 的性能

数据库原理与应用(SQL Server)笔记 第十章 用户定义函数

开工第二天

用户自定义函数

多语句表值函数与内联表值函数