sql-server - tSQLt 测试中的模拟和安全权限如何工作?

标签 sql-server testing sql-server-2016 tsqlt

我有一个 tSQLt 测试,我预计它会失败,但它运行成功。当我在过程外运行代码时,它按预期失败了,但是当使用 Run 执行测试时,没有发生错误。

我已阅读问题 tSQLt Testing SQL Server security permissions但接受的答案并不能解决我的问题。

我的测试是这样的:

    CREATE PROCEDURE TestSecurity.[test AFDK_Reader cannot read from AWS schema]
    AS 
    BEGIN
        --EXEC tSQLt.ExpectException
        EXECUTE AS USER = 'AFDK_Reader'

        select *
        from sys.user_token

        SELECT * FROM fn_my_permissions('AWS', 'SCHEMA')   
        ORDER BY subentity_name, permission_name ;   

        SELECT *
        FROM [AWS].[ADRESSEPUNKT_HISTORIK]
        REVERT
    END

该角色仅授予对 AFDK 架构的选择权限,这是 SQL 用户拥有的唯一数据库角色成员身份。

AFDK_Reader 没有从 AWS 架构中读取的权限。

谁能告诉我如何进行调试?提前致谢。

最佳答案

EXECUTE AS...REVERT 命令在存储过程中的行为方式与您期望的不同。这是 SQL Server 中存储过程安全性的一般特征;存储过程的一种常见用途是抽象权限。 MS 文档页面 Customizing Permissions with Impersonation in SQL Server说:

SQL Server does not check the permissions of the caller if the stored procedure and tables have the same owner.

这实际上就是这里发生的事情。即使 EXECUTE AS 更改了安全上下文,存储过程内部也不会检查该安全上下文。

文档页面还说:

However, ownership chaining doesn't work if objects have different owners or in the case of dynamic SQL.

获得您期望的行为的一种方法是从动态 SQL 语句内部运行 SELECT 语句,这意味着针对表权限测试事件安全上下文:

CREATE PROCEDURE TestSecurity.[test AFDK_Reader cannot read from AWS schema]
AS 
BEGIN
    EXEC tSQLt.ExpectException
    EXECUTE AS USER = 'AFDK_Reader'

    EXEC ('SELECT * FROM [AWS].[ADRESSEPUNKT_HISTORIK]')
    REVERT
END

另一种(更好的?)解决方案可能是使用内置权限函数通过元数据测试权限设置。这是一种方法,仍然使用 EXECUTE AS...REVERTsys.fn_my_permission :

CREATE PROCEDURE TestSecurity.[test AFDK_Reader cannot read from AWS schema]
AS 
BEGIN
    EXECUTE AS USER = 'AFDK_Reader'
    DECLARE @permissionCount int = (SELECT COUNT(*) FROM sys.fn_my_permissions('[AWS].[ADRESSEPUNKT_HISTORIK]', 'OBJECT') WHERE permission_name = 'SELECT' AND subentity_name = '')
    REVERT
    EXEC tSQLt.AssertEquals 0, @permissionCount
END

关于sql-server - tSQLt 测试中的模拟和安全权限如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134978/

相关文章:

android - 当您的应用程序代码中有 try-catch 时,Robolectric 测试中的错误上升

java - 如何从 Cucumber-java 中的日期选择器中选择值

sql-server - 从 SQL Server 中的表中查找可用范围

sql-server - 如何在 ubuntu 12.04 中安装 mssql

sql-server - SSIS将动态结果集变量写入MSSQL表

sql - SQL Server 中嵌套查询有结果或没有结果时如何返回 Yes 或 No?

unit-testing - 模拟聚合类

sql-server - 我可以在 SQL 查询中使用什么来帮助我确定为什么我的查询没有返回任何数据结果

sql-server - 导入数据层应用程序失败

sql - 在 SQL SERVER 的 UPDATE 语句中使用 CASE 选择 SET 的列