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