Налаштування прав користувача для різних схем SQL Server


16

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

Я намагаюся зробити наступне:

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

Ось що я спробував:

  1. Створіть user1 користувача, відображеного на тестовий логін із випадковим паролем
  2. Створив кілька таблиць на схемі dbo з деякими тестовими даними в них
  3. Створено схему схеми1
  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

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

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

Що мені потрібно - це користувач1, щоб мати доступ до даних за допомогою збережених процедур, які я їм надаю, і нічого іншого.

Крім того, це покликане врешті-решт жити на існуючій базі даних SQL Azure, але я спочатку тестую локальну базу даних.


Зверніться до моєї відповіді: Як приховати схему від користувача. Повідомте мене, якщо вам потрібно ще роз'яснення.
Кін Шах

1
Це, здається, зробило це мені більш зрозумілим. Я думаю, що проблема полягала в тому, що у мене був власник Schema1, встановлений на User1, замість dbo. Я встановив, що Schema1 належить користувачеві User1, адаптувався і дотримувався питання, і мені вдалося щось працювати. Ви можете запропонувати відповідь на питання, якщо хочете. Спасибі!
Julia McGuigan

Радий, що тобі це допомогло.
Кін Шах

Відповіді:


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 SP-схемиB

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

Перевірте це, щоб побачити, чи користувач UserA може запустити SP із схемиB. Це буде PASS

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 може бачити схему A, а НЕ схемуB. Хороша річ, що ви можете просто додати користувачів до 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
Для того, щоб ще раз зазначити, важливо, щоб обидві схеми належать одному користувачеві. Це було головне питання у мене.
Julia McGuigan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.