การตั้งค่าการอนุญาตของผู้ใช้สำหรับสคีมา SQL Server ต่างๆ


16

ฉันจำเป็นต้อง จำกัด การเข้าถึงผู้ใช้เฉพาะ แต่พวกเขายังต้องสามารถดูข้อมูลในตารางที่ dbo เป็นเจ้าของได้

ฉันกำลังพยายามทำสิ่งต่อไปนี้:

  1. ฟังก์ชั่น dbo schema ตามปกติจะสามารถเข้าถึงทุกสิ่ง
  2. schema1 schema มีการเข้าถึงวัตถุ schema1 เท่านั้น
  3. ถ้ามุมมอง schema1 หรือกระบวนงานที่เก็บไว้เข้าถึงข้อมูลในตารางที่ dbo เป็นเจ้าของห่วงโซ่การอนุญาตอย่างเหมาะสม
  4. user1 มีสิทธิ์เข้าถึง schema1 และไม่มีอะไรอื่นอีก ยกเว้นในกรณีของ # 3

นี่คือสิ่งที่ฉันได้ลอง:

  1. สร้างผู้ใช้ user1 ที่แมปกับการเข้าสู่ระบบทดสอบด้วยรหัสผ่านแบบสุ่ม
  2. สร้างตารางคู่ใน dbo schema ด้วยข้อมูลการทดสอบบางอย่าง
  3. สร้างสคีมา 1
  4. สร้าง schema1.get_profiles ที่เลือกจากมุมมองที่เรียกว่า schema1.profiles ซึ่งเข้าถึงข้อมูลใน dbo.people, dbo.taglinks และ dbo.tags

อย่างไรก็ตามการใช้คำสั่งต่อไปนี้ในขณะที่เข้าสู่ระบบในฐานะผู้ใช้ 1:

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 ที่มีอยู่ในที่สุด แต่ฉันกำลังทดสอบกับฐานข้อมูลท้องถิ่นก่อน


อ้างถึงคำตอบของฉัน: วิธีซ่อนสคีมาจากผู้ใช้แจ้งให้เราทราบหากคุณต้องการคำชี้แจงเพิ่มเติม
Kin Shah

1
ดูเหมือนว่าจะทำให้ฉันชัดเจนยิ่งขึ้น ฉันคิดว่าปัญหาคือฉันมีเจ้าของ Schema1 ตั้งค่าเป็น User1 แทนที่จะเป็น dbo ฉันตั้งค่า Schema1 ให้เป็นเจ้าของโดย User1 ดัดแปลงและทำตามคำถามและฉันก็สามารถทำงานได้ คุณอาจเสนอคำตอบสำหรับคำถามหากคุณต้องการ ขอบคุณ!
Julia McGuigan

ดีใจที่มันช่วยคุณ
Kin Shah

คำตอบ:


17

แนวคิดพื้นฐานคือการใช้GRANT / ปฏิเสธ Schema สิทธิ์ คุณสามารถจัดการสิทธิ์อย่างมีประสิทธิภาพโดยการสร้างบทบาทและเพิ่มสมาชิกในนั้น

ด้านล่างนี้เป็นตัวอย่างที่จะอธิบายรายละเอียดของคุณ

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 สามารถดู schemaA และ NOT 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 แต่ก็ยังสามารถเรียกใช้ procs จาก SchemaB ได้

ด้านล่างจะอธิบายลำดับชั้นการอนุญาต :

ป้อนคำอธิบายรูปภาพที่นี่


2
เพียงเพื่อย้ำอีกครั้งเป็นสิ่งสำคัญที่ schema ทั้งสองเป็นเจ้าของโดยผู้ใช้เดียวกัน นั่นคือปัญหาหลักที่ฉันมี
Julia McGuigan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.