Проблемы разрешений хранимых процедур SQL-схем - PullRequest
0 голосов
/ 04 мая 2019

При условии упрощенной хранимой процедуры

CREATE OR ALTER PROCEDURE [FooSchema].[Foo]
AS
SELECT
    B.*,
    FROM [BarSchema].[Bar] AS B
    WHERE [...]

После предоставления EXEC пользователю на FooSchema, но не на BarSchema, эта хранимая процедура завершится ошибкой с сообщением

The SELECT permission was denied on the object 'Bar',

Есть ли способ заставить пользователя обращаться к [FooSchema]. [Foo], не раскрывая весь набор данных [BarSchema]. [Bar], поскольку хранимая процедура уже отфильтровывает данные, относящиеся к этому пользователю.

Ответы [ 2 ]

3 голосов
/ 04 мая 2019

Самый простой вариант - использовать оператор [WITH EXECUTE AS], где указанное имя пользователя имеет точные разрешения, необходимые для рассматриваемых объектов.

CREATE OR ALTER PROCEDURE [FooSchema].[Foo]
WITH EXECUTE AS '<username>'
AS
SELECT
    B.*,
    FROM [BarSchema].[Bar] AS B
    WHERE [...]
2 голосов
/ 04 мая 2019

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

Например:

CREATE USER SchemaOwner WITHOUT LOGIN;
ALTER AUTHORIZATION ON SCHEMA::FooSchema TO SchemaOwner;
ALTER AUTHORIZATION ON SCHEMA::BarSchema TO SchemaOwner;

Другой способ предоставления дополнительных разрешений только в рамках модуля - подпись модуля.

CREATE CERTIFICATE FooUserCertificate
   ENCRYPTION BY PASSWORD = '0bfuscatedPassword'
   WITH SUBJECT = 'Allow access to bar table';

CREATE USER FooUser FROM CERTIFICATE FooUserCertificate;

GRANT SELECT ON BarSchema.Bar TO FooUser;

ADD SIGNATURE TO FooSchema.Foo BY CERTIFICATE FooUserCertificate
    WITH PASSWORD = '0bfuscatedPassword';

ALTER CERTIFICATE FooUserCertificate REMOVE PRIVATE KEY;
GO

Хотя и сложнее, преимущество подписывания модуля над EXECUTE AS заключается в том, что исходная идентификация вызывающего абонента сохраняется во время выполнения и не помещается в изолированную программную среду в текущей базе данных. Это полезно для аудита и доступа к базе данных. См. эту статью для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...