Установка пользовательских разрешений для разных схем SQL Server

16

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

Я пытаюсь сделать следующее:

  1. Схема dbo функционирует как обычно, имеет доступ ко всему
  2. Схема1 имеет доступ только к объектам схемы1.
  3. если представление схемы или хранимая процедура обращается к данным в таблицах, принадлежащих dbo, цепочка разрешений соответственно
  4. user1 имеет доступ к schema1 и больше ничего; за исключением случая № 3

Вот что я попробовал:

  1. Создайте пользователя user1, сопоставленного с тестовым логином со случайным паролем
  2. Создал пару таблиц в схеме dbo с некоторыми тестовыми данными в них
  3. Создана схема schema1
  4. Создал schema1.get_profiles, который выбирает из представления с именем schema1.profiles, которое обращается к данным в dbo.people, dbo.taglinks и dbo.tags

Тем не менее, используя следующий оператор при входе в систему как user1:

EXEC get_profiles 1

результаты в:

The SELECT permission was denied on the object 'tags', database 'schema_test', schema 'dbo'.

Я пытался WITH EXECUTE AS OWNERи не могу понять, как «цепочка владения» должна работать.

Я также пытался

GRANT EXECUTE ON SCHEMA::schema1 TO user1
GRANT INSERT ON SCHEMA::schema1 TO user1
GRANT SELECT ON SCHEMA::schema1 TO user1
GRANT UPDATE ON SCHEMA::schema1 TO user1
GRANT VIEW DEFINITION ON SCHEMA::schema1 TO user1

но я получаю следующую ошибку (несмотря на то, что пользователь с уровнем доступа dbo):

Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.

Что мне нужно, так это user1, чтобы иметь возможность доступа к данным через хранимые процедуры, которые я им предоставляю, и ничего больше

Кроме того, это в конечном итоге предназначено для использования в существующей базе данных SQL Azure, но сначала я проверяю локальную фиктивную базу данных.

Джулия Макгиган
источник
Обратитесь к моему ответу: Как скрыть схему от пользователя. Дайте мне знать, если вам нужно больше разъяснений.
Кин Шах
1
Это, кажется, сделало это более ясным для меня. Я думаю, что проблема была в том, что у меня был владелец Schema1 в User1 вместо dbo. Я установил, что Schema1 будет принадлежать User1, адаптировался и последовал за вопросом, и я смог заставить что-то работать. Вы можете предложить ответ на вопрос, если хотите. Благодарность!
Джулия Макгиган
Рад, что это помогло тебе.
Кин Шах

Ответы:

17

Основная концепция заключается в использовании разрешений схемы GRANT / DENY . Вы можете эффективно управлять разрешениями, создав роль и добавив в нее участников.

Ниже приведен пример, который подробно объяснит вам

use master
go
--Create Logins
CREATE LOGIN UserA WITH Password='UserA123';
go
CREATE LOGIN UserB WITH Password='UserB123';

use AdventureWorks2008R2
go
--Create Database Users
CREATE USER UserA;
go
CREATE USER UserB;
go
--Create the Test Schemas
CREATE SCHEMA SchemaA AUTHORIZATION UserA
go
CREATE SCHEMA SchemaB AUTHORIZATION UserB
go

-- create test tables
create table schemaA.TableA (fname char(5))
go
insert into schemaA.TableA (fname) values ('Kin-A')
go

create table SchemaB.TableB (fname char(5))
go
insert into SchemaB.TableB (fname) values ('Kin-B')
go

Сейчас тестируем:

--Test for UserA in SchemaA
EXEC('select * from schemaA.TableA') AS USER = 'UserA'
go
--Kin-A

-- Test for UserB in SchemaB == this should fail
EXEC('select * from SchemaB.TableB') AS USER = 'UserA'
go
--Msg 229, Level 14, State 5, Line 1
--The SELECT permission was denied on the object 'TableB', database 'AdventureWorks2008R2', schema 'SchemaB'.

Теперь создайте хранимые процедуры:

CREATE PROCEDURE SchemaB.proc_SelectUserB
AS
    select * from schemaA.TableA;
go
create procedure schemaA.proc_SchemaA
as 
    select * from schemaA.TableA

Теперь предоставьте права на выполнение UserA на SP схемы ScheB.

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [UserA] 
go

Проверьте это .., чтобы увидеть, может ли UserA запускать SP из schemaB. Это пройдет

EXECUTE AS LOGIN='UserA';
    Exec SchemaB.proc_SelectUserB;
    revert;
go
--- Kin-A

Но UserA не сможет увидеть данные из SchemaB

EXECUTE AS LOGIN='UserA';
    select * from SchemaB.TableB
revert;
go

--- Msg 229, Level 14, State 5, Line 3
--- The SELECT permission was denied on the object 'TableB', database 'AdventureWorks2008R2', schema 'SchemaB'.

В качестве альтернативы вы можете использовать DATABASE ROLE и просто добавить к ней пользователей для лучшей управляемости разрешений:

EXEC sp_addrole 'SchemaBUsesSchemaAProc'
go
EXEC sp_addrolemember 'SchemaBUsesSchemaAProc','UserA';
go

Нижеприведенный оператор убедится, что UserA может видеть schemaA, а НЕ schemaB. Хорошо, что вы можете просто добавить пользователей к SchemaBUsesSchemaAProcроли, и они унаследуют все разрешения, предоставленные этой роли.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

Если вы хотите, чтобы UserA мог выполнять SP, принадлежащие SchemaB, то нижеприведенный оператор выполнит эту работу:

GRANT EXECUTE ON OBJECT::[SchemaB].[proc_SelectUserB] TO [SchemaBUsesSchemaAProc] 
go

Таким образом, UserA не может видеть таблицы SchemaB, но все же может выполнять процессы из SchemaB.

Ниже поясняется иерархия разрешений :

введите описание изображения здесь

Кин Шах
источник
2
Просто повторюсь, важно, чтобы обе схемы принадлежали одному и тому же пользователю. Это была главная проблема, с которой я столкнулся.
Джулия Макгиган