Saya khawatir deskripsi Anda atau konsepsi Anda tentang Rantai Kepemilikan tidak jelas, jadi izinkan saya memulai dengan itu:
"Rantai Kepemilikan" hanya mengacu pada fakta bahwa ketika menjalankan Prosedur Tersimpan (atau Tampilan) di SQL Server, batch yang saat ini dieksekusi untuk sementara memperoleh hak/izin Pemilik sProc (atau Pemilik skema sProc) saat mengeksekusi kode SQL itu. Jadi dalam kasus sProc, Pengguna tidak dapat menggunakan privs tersebut untuk melakukan apa pun yang tidak diterapkan oleh kode sProc untuk mereka. Perhatikan khususnya bahwa ia tidak pernah memperoleh Identitas Pemilik, hanya haknya, untuk sementara (namun, EXECUTE AS... melakukan ini).
Jadi pendekatan umum untuk memanfaatkan ini demi keamanan adalah dengan:
-
Masukkan semua Tabel Data (dan semua Tampilan non-keamanan juga) ke dalam Skema mereka sendiri, sebut saja [data] (meskipun biasanya [dbo] digunakan karena sudah ada dan terlalu istimewa untuk skema Pengguna). Pastikan tidak ada Pengguna, Skema, atau Pemilik yang memiliki akses ke skema [data] ini.
-
Buat skema yang disebut [exec] untuk semua sProcs (dan/atau mungkin Tampilan keamanan apa pun). Pastikan pemilik skema ini memiliki akses ke skema [data] (ini mudah jika Anda menjadikan dbo sebagai pemilik skema ini).
-
Buat db-Role baru bernama "Users" dan berikan akses EXECUTE ke skema [exec]. Sekarang tambahkan semua pengguna ke peran ini. Pastikan pengguna Anda hanya memiliki hak Terhubung dan tidak memiliki akses yang diberikan ke skema lain, termasuk [dbo].
Sekarang pengguna Anda dapat mengakses data hanya dengan menjalankan sProcs di [exec]. Mereka tidak dapat mengakses data lain atau mengeksekusi objek lain.
Saya tidak yakin apakah ini menjawab pertanyaan Anda (karena saya tidak yakin persis apa pertanyaannya), jadi jangan ragu untuk mengarahkan saya.
Untuk keamanan tingkat baris, berikut adalah cara saya selalu melakukannya dengan skema keamanan di atas:
-
Saya selalu menerapkan keamanan tingkat baris sebagai serangkaian Tampilan yang mencerminkan setiap tabel dan membandingkan identitas Pengguna (biasanya dengan Suser_Sname() atau salah satunya) dengan daftar keamanan yang dikunci dari kode keamanan di baris itu sendiri. Ini adalah Tampilan Keamanan.
-
Buat skema baru yang disebut [baris], berikan pemiliknya akses ke skema [data] dan tidak ada yang lain. Letakkan semua Tampilan Keamanan dalam skema ini.
-
Cabut akses pemilik [exec] ke skema [data] dan berikan akses data ke skema [baris].
Selesai. Sekarang keamanan tingkat baris telah diterapkan dengan menyelipkannya secara transparan di antara sProcs dan tabel.
Akhirnya, ini adalah pengadaan tersimpan yang saya gunakan untuk membantu saya mengingat seberapa banyak hal keamanan yang tidak jelas ini bekerja dan berinteraksi dengan dirinya sendiri (oops, versi kode yang dikoreksi ):
CREATE proc [TestCnxOnly].[spShowProc_Security_NoEX] as
--no "With Execute as Owner" for this version
--create User [UserNoLogin] without login
--Grant connect on database :: TestSecurity to Guest
--alter database TestSecurity set trustworthy on
--Show current user context:
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (sproc)]
, suser_sname() as sname
, system_user as system_
--Execute As Login = 'UserNoLogin'
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (after exec as)]
, suser_sname() as sname
, system_user as system_
EXEC('select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (in Exec(sql))]
, suser_sname() as sname
, system_user as system_')
EXEC sp_ExecuteSQL N'select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (in sp_Executesql)]
, suser_sname() as sname
, system_user as system_'
--Revert
select current_user as current_
, session_user as session
, user_name() as _name
, suser_name() as [suser (aftr revert)]
, suser_sname() as sname
, system_user as system_
[EDIT:versi kode yang dikoreksi)