Просмотр и таблица разрешения конфликтов безопасности - PullRequest
0 голосов
/ 01 ноября 2019

У меня есть экземпляр SQL Server 2017 с 5 базами данных. A, B, C, D, E. База данных A содержит только схемы и представления. Существует одна схема для каждой из последующих баз данных в экземпляре (A, B, C, D, E), и каждая схема имеет 50 - 150 представлений, которыми она владеет.

Мне нужна возможность предоставить пользователям выбор разрешений для всех представлений в базе данных A, но запретить полномочия выбора для ВСЕХ таблиц напрямую.

Условия теста должны выглядеть следующим образом.

SELECT * FROM [B].dbo.[any_table] (DENIED)
SELECT * FROM [A].[B].some_view (WORKS)

Поскольку все схемы A - E принадлежат dbo, я предположил, что могу просто сделать следующее:

USE A
GO

CREATE ROLE db_viewreader
GO

GRANT SELECT ON SCHEMA::A TO db_viewreader (repeat for b, c, d, e)
GO

CREATE USER testuser WITHOUT LOGIN
GO
ALTER ROLE db_viewreader ADD MEMBER testuser
GO

EXECUTE AS USER = 'testuser'

SELECT *
FROM [A].[B].some_view

Я не могу получить результаты из представления или таблицы. Я думаю, я понимаю, почему я не получаю результаты, запрашивая таблицы, поскольку созданный мной пользователь не существует в базе данных B - E. По этой же причине я не могу вызвать представление, которое обращается к данным в этих базовых таблицах? Если да, то есть ли способ создать пользователя, который будет использовать представления, но не таблицы, над которыми они расположены?

1 Ответ

1 голос
/ 01 ноября 2019

Можно разрешить SELECT для представлений без разрешений для базовых таблиц с цепочкой владения . Пока все задействованные объекты принадлежат одному и тому же субъекту безопасности, цепочка владения позволит пользователям, которым предоставлены разрешения для представления, использовать его независимо от разрешений для таблиц, на которые ссылается представление.

Существуют и другие соображенияиспользовать цепочку владения объектами в разных базах данных.

  • Для задействованных баз данных должна быть включена опция DB_CHAINING или включена опция уровня сервера cross db ownership chaining:

    ALTER DATABASE A SET DB_CHAINING ON;
    ALTER DATABASE B SET DB_CHAINING ON;
    ALTER DATABASE C SET DB_CHAINING ON;
    ALTER DATABASE D SET DB_CHAINING ON;
    ALTER DATABASE E SET DB_CHAINING ON;
    
  • Пользователь должен быть участником уровня сервера и добавляться в каждую базу данных (или гостевой пользователь должен быть включен в другие базы данных):

    CREATE LOGIN testuser WITH PASSWORD = 'n3$(s(+#BB4--';
    USE A;CREATE USER testuser;ALTER ROLE db_viewreader ADD MEMBER testuser;
    USE B;CREATE USER testuser;
    USE C;CREATE USER testuser;
    USE D;CREATE USER testuser;
    USE E;CREATE USER testuser;
    
  • Владелец объекта, обычно наследуемый от схемы объекта AUTHORIZATION, должен быть одним и тем же субъектом безопасности для всех задействованных объектов. В случае пользователя dbo это логин владельца базы данных:

    ALTER AUTHORIZATION ON DATABASE::A TO DatabaseOwnerLogin;
    ALTER AUTHORIZATION ON DATABASE::B TO DatabaseOwnerLogin;
    ALTER AUTHORIZATION ON DATABASE::C TO DatabaseOwnerLogin;
    ALTER AUTHORIZATION ON DATABASE::D TO DatabaseOwnerLogin;
    ALTER AUTHORIZATION ON DATABASE::E TO DatabaseOwnerLogin;
    

Обратите внимание, что в таблицах нет необходимости в явном объяснении DENY, если только вы не 'мы предоставили пользователю права доступа к таблице напрямую или через членство в роли. Пользователи по умолчанию не имеют никаких прав доступа к объектам, если они не предоставлены.

Чтобы протестировать разрешения, вам необходимо выдать себя за пользователя уровня сервера, а не за пользователя базы данных, поскольку в противном случае пользователь db будет помещен в изолированную среду в контекстной базе данных (если только база данныхis TRUSTWORTHY):

USE A;
GO
EXECUTE AS LOGIN = 'testuser';
GO
SELECT *
FROM [A].[B].some_view;
GO
REVERT;
GO

Обратите внимание, что цепочка владения для разных баз данных по умолчанию отключена по причинам, указанным в выдержке из документации ниже. Это может не беспокоить, когда только члены роли sysadmin могут создавать объекты базы данных в рабочих базах данных и, конечно, просматривать код перед развертыванием.

Владельцы базы данных и члены ролей базы данных db_ddladmin или db_owners могут создавать объекты, принадлежащие другим пользователям. Эти объекты могут потенциально предназначаться для объектов в других базах данных. Это означает, что если вы включаете цепочку владения несколькими базами данных, вы должны полностью доверять этим пользователям данные во всех базах данных.

...