我对 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)
根据文档,我希望通过视图插入也会失败。
但它之所以有效,是因为有一个名为Ownership chaining的概念。官方教程在这里
当您有权访问一个对象(在本例中为 v.view1)并且该对象引用具有相同所有者(sch1.table1)的安全对象时,根本不会检查权限。
由于两个对象都没有明确的所有者:
资源
和架构所有者可以在这里找到
您可以通过更改架构v的所有者来打破所有权链,如下所示:
然后你会得到你期望的拒绝。