Eu tive uma observação interessante sobre as permissões de segurança do SQL Server.
Minha configuração é como abaixo. Estou tentando restringir o usuário de atualizar tabelas em esquema específico.
A declaração do problema é Por que o usuário tem permissão para fazer inserções na tabela por meio da exibição (de esquema diferente), mesmo que a inserção seja explicitamente negada no esquema da tabela na definição da exibição?
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)
Com base na documentação , eu esperaria que o insert through view falhasse também.
Mas funciona por causa de um conceito chamado Encadeamento de propriedade . Tutorial oficial está aqui
Quando você tem acesso a um objeto (neste caso v.view1 ) e esse objeto faz referência a um protegível com o mesmo proprietário ( sch1.table1 ), as permissões não são verificadas.
Como ambos os objetos não têm proprietário explícito:
fonte
e o proprietário do esquema podem ser encontrados aqui
Você pode quebrar a cadeia de propriedade alterando o proprietário do esquema v assim:
Então você obterá o DENY que você espera.