Как вы устанавливаете разрешения для схемы, объекты которой имеют доступ к другим схемам? - PullRequest
1 голос
/ 02 ноября 2009

У меня есть 2 схемы, и один из объектов в первой схеме должен получить доступ к объекту в другой схеме. Например:

CREATE VIEW I.ITest
AS
    SELECT 1 as TestColumn
GO
CREATE VIEW O.OTest
AS
    SELECT * FROM I.ITest
GO

EXEC ('SELECT * FROM O.OTest') AS USER = 'TestUser'

DROP VIEW O.OTest
DROP VIEW I.ITest

В приведенном выше примере TestUser имеет доступ только к схеме «O». Таким образом, само выделение работает нормально, но поскольку представление делает выбор из другой схемы 'I', то происходит сбой с ошибкой:

Отказано в разрешении SELECT для объекта «ITest», базы данных «MyDB», схемы «I».

Чтобы обойти это, я могу дать схеме «O» разрешение на доступ к схеме «I», но это звучит неправильно и выглядит как обход разрешений схемы.

Что можно сделать? Я делаю все это неправильно? Какова лучшая практика в этом сценарии?

Спасибо

ОБНОВЛЕНИЕ : Мои схемы принадлежали разным ролям db, поэтому я решил эту проблему, просто изменив владельца обоих на dbo, а затем предоставив разрешение роли db для доступа к схеме. Это означало, что владелец dbo мог видеть все, и я мог тогда дать конкретное разрешение только на роль db, а остальные объекты db были недоступны, если только через эту схему. Спасибо за вашу помощь

Ответы [ 2 ]

1 голос
/ 02 ноября 2009

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

1 голос
/ 02 ноября 2009

Вы должны заключить выборку данных из представления в «другую» схему в хранимую процедуру. Затем предоставьте права на выполнение хранимой процедуры. Хотя пользователь не будет иметь прямого доступа к представлению, ему разрешен доступ через хранимую процедуру.

Вот примерное пошаговое руководство для демонстрации принципов безопасности как работы:

USE DATABASE SANDBOX;

--Create Logins
CREATE LOGIN UserOne WITH Password='Hello123';
CREATE LOGIN UserTwo WITH Password='Hello123';

--Create Database Users
CREATE USER UserOne;
CREATE USER UserTwo;

--Create the Test Schemas
CREATE SCHEMA SchemaOne AUTHORIZATION UserOne;
CREATE SCHEMA SchemaTwo AUTHORIZATION UserTwo;

--Create a View on SchemaOne
CREATE VIEW SchemaOne.ViewOne
AS SELECT 1 as TestColumn;

--Create a View on SchemaTwo
CREATE VIEW SchemaTwo.ViewTwo
AS SELECT * FROM SchemaOne.ViewOne;

--Test that the SchemaOne
EXEC('select * from SchemaOne.ViewOne') AS USER = 'UserOne'
--1

EXEC('select * from SchemaTwo.ViewTwo') AS USER = 'UserOne'
--The SELECT permission was denied on the object 'ViewTwo', database 'SANDBOX', schema 'SchemaTwo'.

--Create a stored procedure to safely expose the view within SchemaTwo to UserOne who's default Schema is
--SchemaOne.
CREATE PROCEDURE SchemaTwo.proc_SelectViewTwo
AS
    select * from SchemaTwo.ViewTwo;

--Grant execute rights on the procedure
GRANT EXECUTE ON SchemaTwo.proc_SelectViewTwo TO UserOne;

--Test the 
EXECUTE AS LOGIN='UserOne';
    Exec SchemaTwo.proc_SelectViewTwo;
revert;

Альтернативный подход, предложенный в моих комментариях, заключается в использовании роли базы данных для управления доступом к нескольким схемам. Используя принципы, определенные в приведенном выше решении, вы можете использовать роли базы данных следующим образом:

EXEC sp_addrole 'CrossSchemaRole';
EXEC sp_addrolemember 'CrossSchemaRole','UserOne';

GRANT SELECT ON SCHEMA::SchemaOne TO CrossSchemaRole;
GRANT SELECT ON SCHEMA::SchemaTwo TO CrossSchemaRole;

EXECUTE AS LOGIN='UserOne';
    select * from SchemaTwo.ViewTwo;
revert;

Некоторые предложили продолжить чтение:

...