我对 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)
根据文档,我预计通过视图插入也会失败。
需要对目标表具有 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)
然后你会得到你期望的拒绝。
归档时间: |
|
查看次数: |
428 次 |
最近记录: |