it-swarm.asia

تعيين أذونات المستخدم لمخططات SQL Server مختلفة

أحتاج إلى تقييد الوصول إلى مستخدم معين ، ولكن لا يزال عليهم أن يكونوا قادرين على رؤية البيانات في الجداول المملوكة لـ dbo.

أحاول القيام بما يلي:

  1. يعمل مخطط dbo كما هو معتاد ، يمكنه الوصول إلى كل شيء
  2. مخطط schema1 لديه حق الوصول إلى كائنات المخطط 1 فقط
  3. إذا كان عرض المخطط 1 أو الإجراء المخزن يصل إلى البيانات في جداول مملوكة لـ dbo ، فإن سلسلة الأذونات مناسبة
  4. user1 لديه حق الوصول إلى المخطط 1 ، ولا شيء آخر ؛ باستثناء حالة رقم 3

إليك ما حاولت:

  1. قم بإنشاء مستخدم 1 تم تعيينه لتسجيل دخول تجريبي باستخدام كلمة مرور عشوائية
  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

ولكني أتلقى الخطأ التالي (على الرغم من أنني مستخدم لديه وصول على مستوى dbo):

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

ما أحتاج إليه هو user1 حتى أتمكن من الوصول إلى البيانات من خلال الإجراءات المخزنة التي أعطيها ، ولا شيء آخر.

بالإضافة إلى ذلك ، الغرض من هذا هو العيش في نهاية المطاف على قاعدة بيانات SQL Azure الموجودة ، لكنني أختبر أولاً ضد قاعدة بيانات وهمية محلية.

16
Julia McGuigan

المفهوم الأساسي هو استخدام أذونات مخطط 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 في schemaB

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 قادر على رؤية المخطط و ليس المخطط. الشيء الجيد هو أنه يمكنك فقط إضافة مستخدمين إلى دور SchemaBUsesSchemaAProc وسوف يرثون جميع الأذونات الممنوحة لهذا الدور.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

إذا كنت ترغب فقط في السماح للمستخدم (UserA) بتنفيذ نقاط الخدمة المملوكة لـ SchemaB ، فسيؤدي البيان أدناه المهمة:

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

بهذه الطريقة ، UserA غير قادر على رؤية جداول SchemaB ، ولكن لا يزال بإمكانه تنفيذ procs من SchemaB.

أدناه سوف يشرح التسلسل الهرمي للإذن :

enter image description here

17
Kin Shah