数据库角色权限是否优先于架构/对象级别权限?

GAU*_*HOD 5 sql-server

我对 SQL Server 安全权限有一个有趣的观察。

我的设置如下。我试图限制用户更新特定架构下的表。

问题陈述是为什么用户可以通过视图(不同模式)在表上进行插入,即使在视图定义中的表模式上显式拒绝插入?

USE master
GO

CREATE LOGIN Login1
    WITH password = 'Admin@123'
GO

CREATE DATABASE TestDB
GO

USE TestDB
GO

CREATE user Login1
FROM LOGIN Login1
GO

CREATE SCHEMA sch1
GO

CREATE SCHEMA V
GO

CREATE TABLE sch1.table1 (
    id INT
    ,name VARCHAR(5)
    )
GO

CREATE VIEW v.view1
AS
SELECT *
FROM sch1.table1
GO

CREATE VIEW sch1.view2
AS
SELECT *
FROM sch1.table1
GO

--User can update all tables
ALTER ROLE [db_datawriter] ADD MEMBER [Login1] 
GO

--Except tables under this schema
DENY INSERT
    ON SCHEMA::[sch1]
    TO [Login1]
GO



--Open session with Login1
USE TestDB
GO

--Should not work, does not work.
INSERT sch1.table1
SELECT 1, 'A'
--The INSERT permission was denied on the object 'table1', database 'TestDB', schema 'sch1'.


--Should not work, does not work.
INSERT sch1.view2
SELECT 1, 'A'
--The INSERT permission was denied on the object 'view2', database 'TestDB', schema 'sch1'.


-- Works! - even though write is denied on underlying table?
INSERT v.view1
SELECT 1, 'A'
--(1 row affected)

Run Code Online (Sandbox Code Playgroud)

Zik*_*ato 3

根据文档,我预计通过视图插入也会失败。

需要对目标表具有 UPDATE、INSERT 或 DELETE 权限,具体取决于所执行的操作。

但它之所以有效,是因为一个称为“所有权链”的概念。官方教程在这里

当您有权访问一个对象(在本例中为v.view1)并且该对象引用具有相同所有者(sch1.table1)的安全对象时,根本不会检查权限。

由于这两个对象都没有明确的所有者:

默认情况下,架构包含的对象由架构所有者拥有

来源

和模式所有者可以在这里找到

SELECT
    s.name AS schName, dp.name AS ownerUser
FROM sys.schemas AS s 
JOIN sys.database_principals AS dp
    ON dp.principal_id = s.principal_id
WHERE s.name IN (N'v', N'sch1')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

您可以通过更改模式v的所有者来打破所有权链,如下所示:

ALTER AUTHORIZATION ON SCHEMA::v TO Login1
Run Code Online (Sandbox Code Playgroud)

然后你会得到你期望的拒绝。