Menetapkan izin pengguna untuk berbagai skema SQL Server

16

Saya perlu membatasi akses ke pengguna tertentu, tetapi mereka masih harus dapat melihat data dalam tabel yang dimiliki oleh dbo.

Saya mencoba melakukan hal berikut:

  1. skema dbo berfungsi seperti biasanya, memiliki akses ke semuanya
  2. schema1 schema memiliki akses ke hanya obyek schema1
  3. jika skema1 melihat atau prosedur tersimpan mengakses data dalam tabel yang dimiliki oleh dbo, rantai izin tepat
  4. user1 memiliki akses ke schema1, dan tidak ada yang lain; kecuali dalam kasus # 3

Inilah yang saya coba:

  1. Buat pengguna1 pengguna dipetakan ke login uji coba dengan kata sandi acak
  2. Membuat beberapa tabel dalam skema dbo dengan beberapa data uji di dalamnya
  3. Membuat skema skema1
  4. Membuat schema1.get_profiles yang memilih dari tampilan yang disebut schema1.profiles yang mengakses data di dbo.people, dbo.taglinks, dan dbo.tags

Namun, menggunakan pernyataan berikut saat login sebagai user1:

EXEC get_profiles 1

menghasilkan:

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

Saya sudah mencoba WITH EXECUTE AS OWNERdan tidak bisa mulai memahami bagaimana "rantai kepemilikan" seharusnya berfungsi.

Saya juga sudah mencoba

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

tapi saya mendapatkan kesalahan berikut (meskipun menjadi pengguna dengan akses dbo-level):

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

Yang saya butuhkan adalah user1 untuk dapat mengakses data melalui prosedur tersimpan yang saya berikan, dan tidak ada yang lain.

Selain itu, ini dimaksudkan untuk akhirnya hidup pada database SQL Azure yang ada, tapi saya menguji terhadap database dummy lokal terlebih dahulu.

Julia McGuigan
sumber
Lihat jawaban saya: Cara Menyembunyikan Skema dari pengguna Beri tahu saya jika Anda membutuhkan klarifikasi lagi.
Kin Shah
1
Ini sepertinya membuatnya lebih jelas bagi saya. Saya pikir masalahnya adalah saya memiliki pemilik Schema1 diatur ke User1, bukan dbo. Saya menetapkan Schema1 agar dimiliki oleh User1, beradaptasi dan mengikuti pertanyaan, dan saya bisa membuat sesuatu berfungsi. Anda dapat mengajukan jawaban atas pertanyaan itu jika Anda mau. Terima kasih!
Julia McGuigan
Senang itu membantu Anda.
Kin Shah

Jawaban:

17

Konsep dasarnya adalah menggunakan Izin Skema GRANT / DENY . Anda dapat mengelola izin secara efisien dengan membuat peran dan kemudian menambahkan anggota ke dalamnya.

Di bawah ini adalah contoh yang akan menjelaskan Anda secara rinci

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

Sekarang uji:

--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'.

Sekarang buat Prosedur yang Disimpan:

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

Sekarang Berikan izin untuk menjalankan UserA di schemaB's SP

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

Uji .. untuk melihat apakah UserA mampu menjalankan SP dari schemaB. Ini akan LULUS

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

Tetapi UserA tidak akan dapat melihat data dari 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'.

Atau Anda dapat menggunakan DATABASE ROLE dan hanya menambahkan pengguna ke dalamnya untuk pengelolaan izin yang lebih baik:

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

Pernyataan di bawah ini akan memastikan bahwa UserA dapat melihat schemaA dan NOT schemaB. Hal yang baik adalah Anda bisa menambahkan penggunaSchemaBUsesSchemaAProc peran dan mereka akan mewarisi semua izin yang diberikan untuk peran itu.

GRANT SELECT ON SCHEMA::SchemaA TO SchemaBUsesSchemaAProc;
go

Jika Anda hanya ingin mengizinkan UserA untuk menjalankan SP yang dimiliki oleh SchemaB maka pernyataan di bawah ini akan melakukan pekerjaan:

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

Dengan cara ini, UserA tidak dapat melihat tabel SchemaB, tetapi masih dapat menjalankan procs dari SchemaB.

Di bawah ini akan menjelaskan hierarki izin :

masukkan deskripsi gambar di sini

Kin Shah
sumber
2
Hanya untuk mengulangi, penting bahwa kedua skema dimiliki oleh pengguna yang sama. Itulah masalah utama yang saya alami.
Julia McGuigan