Mengapa Keamanan Tingkat Baris Penting?
Sebelum SQL Server 2016, keamanan tingkat tabel adalah tingkat keamanan terendah default untuk database. Dengan kata lain, pengguna dapat dibatasi untuk mengakses tabel secara keseluruhan. Namun, dalam beberapa kasus, kami membutuhkan pengguna untuk memiliki akses ke tabel, tetapi tidak ke baris tertentu di dalam tabel. Sebelum SQL Server 2016, ini memerlukan prosedur tersimpan kustom yang harus ditulis untuk penyediaan keamanan berbutir halus tersebut. Namun, prosedur tersimpan tersebut rentan terhadap injeksi SQL dan peringatan keamanan lainnya.
Menggunakan Fitur Keamanan Tingkat Baris SQL Server saat Latihan
SQL Server 2016 memperkenalkan fitur keamanan tingkat baris baru yang memungkinkan pengguna memiliki akses ke tabel tetapi membatasi mereka untuk mengakses baris tertentu di dalam tabel itu. Mari kita lihat bagaimana ini dapat digunakan secara praktis.
Deskripsi
Ada empat langkah untuk menerapkan keamanan tingkat baris di SQL Server.
- Berikan izin Pilih kepada pengguna di tabel tempat Anda ingin menerapkan keamanan tingkat baris.
- Selanjutnya, Anda harus menulis fungsi nilai tabel sebaris yang berisi predikat filter. Tambahkan logika filter ke predikat filter.
- Terakhir, Anda harus mengikat predikat filter yang Anda buat pada langkah kedua ke kebijakan keamanan.
- Uji fitur keamanan tingkat baris.
Sebelum kita melakukan langkah-langkah di atas, kita perlu membuat database dummy dengan beberapa catatan dummy. Jalankan skrip berikut untuk melakukannya:
CREATE DATABASE UniversityGOUSE UniversityGOUSE UniversityCREATE TABLE Persons(Id INT PRIMARY KEY IDENTITY(1,1),Name VARCHAR (50),Role VARCHAR (50))GOUSE UniversityINSERT INTO Persons VALUES ('Sally', 'Principal' )INSERT INTO NILAI Orang ('Edward', 'Student' )INSERT INTO Persons VALUES ('Jon', 'Student' )INSERT INTO Persons VALUES ('Scot', 'Student')INSERT INTO Persons VALUES ('Ben', 'Student' ) INSERT INTO Persons NILAI ('Isabel', 'Teacher' )INSERT INTO Persons VALUES ('David', 'Teacher' )INSERT INTO Persons VALUES ('Laura', 'Teacher' )INSERT INTO Persons VALUES ('Jean', 'Guru ')INSERT INTO Persons VALUES ('Francis', 'Guru' )
Dalam skrip, kami membuat database dummy "Universitas". Selanjutnya, kami menjalankan skrip yang membuat tabel bernama "Orang". Jika Anda melihat desain tabel, Anda dapat melihat bahwa itu berisi tiga kolom Id, Name dan Role. Kolom Id adalah kolom kunci utama dengan batasan IDENTITY. Kolom Name berisi nama orang dan kolom Role berisi peran orang tersebut. Akhirnya, kami memasukkan 10 record ke dalam tabel Persons. Tabel memiliki 1 Kepala Sekolah, 4 guru, dan 5 siswa.
Mari kita jalankan pernyataan SELECT sederhana untuk melihat record dalam tabel:
Gunakan UniversitySELECT * FROM Persons
Hasilnya terlihat seperti ini:
Kami ingin pengguna bernama Principal memiliki akses ke semua baris dalam tabel Persons. Demikian pula, seorang Guru harus memiliki akses hanya ke catatan Guru, sedangkan Siswa harus memiliki akses hanya ke catatan Siswa. Ini adalah kasus klasik keamanan tingkat baris.
Untuk menerapkan keamanan tingkat baris, kita akan mengikuti langkah-langkah yang telah kita bahas sebelumnya.
Langkah 1:Berikan Izin Pilih kepada Pengguna di Tabel
Mari buat tiga pengguna dengan peran Kepala Sekolah, Guru, dan Siswa dan beri mereka akses PILIH ke pengguna ini di tabel Orang. Jalankan skrip berikut untuk melakukannya:
BUAT USER Kepala Sekolah TANPA LOGIN;GOCREATE USER Guru TANPA LOGIN;GOCREATE PENGGUNA Siswa TANPA LOGIN;GOUse UniversityGRANT SELECT ON Persons TO Principal;GOGRANT SELECT ON Persons TO Teacher;GOGRANT SELECT ON Persons TO Student;GO
Langkah 2:Membuat Predikat Filter
Setelah pengguna diberikan izin, langkah selanjutnya adalah membuat predikat filter.
Skrip berikut melakukannya:
Gunakan UniversityGOCREATE FUNCTION dbo.fn_SP_Person(@Role AS sysname) RETURNS TABLEWITH SCHEMABINDINGAS RETURN SELECT 1 AS fn_SP_Person_output -- Logika predikat WHERE @Role =USER_NAME() OR USER_NAME() ='GOPredikat filter dibuat di dalam fungsi bernilai tabel sebaris dan mengambil peran pengguna sebagai parameter. Ini mengembalikan catatan di mana nilai Peran yang diteruskan sebagai parameter cocok dengan nilai peran di kolom Peran. Atau jika peran pengguna adalah 'Principal', semua peran dikembalikan. Jika Anda melihat filter predikat, Anda tidak akan menemukan nama tabel yang kami buatkan filternya. Predikat filter terhubung ke tabel melalui kebijakan keamanan yang akan kita lihat di langkah selanjutnya.
Langkah 3:Membuat Kebijakan Keamanan
Jalankan skrip berikut untuk membuat kebijakan keamanan untuk predikat filter yang kita buat di langkah terakhir:
Gunakan UniversityGoCREATE SECURITY POLICY RoleFilterADD FILTER PREDICATE dbo.fn_SP_Person(Role)ON dbo.PersonsWITH (STATE =ON);GODalam kebijakan Keamanan, kami hanya menambahkan predikat filter yang kami buat ke tabel Orang. Untuk mengaktifkan kebijakan, bendera “STATE” harus disetel ke AKTIF.
Langkah 4:Menguji Keamanan Tingkat Baris
Kami melakukan semua langkah yang diperlukan untuk menegakkan keamanan tingkat baris pada tabel Persons dari database Universitas. Pertama-tama mari kita coba mengakses catatan di tabel Persons melalui pengguna default. Jalankan script berikut:
Gunakan UniversitySELECT * FROM Persons;GOAnda tidak akan melihat apa pun di output karena pengguna default tidak dapat mengakses tabel Persons.
Mari beralih ke pengguna Siswa yang kita buat sebelumnya dan coba PILIH catatan dari tabel Orang:
EXECUTE AS USER ='Student';Gunakan UniversitySELECT * FROM Persons; -- Catatan Siswa SajaREVERT;GODalam skrip di atas, kami beralih ke pengguna 'Siswa', catatan yang dipilih dari tabel Orang dan kembali ke pengguna default. Outputnya terlihat seperti ini:
Anda dapat melihat bahwa karena keamanan tingkat baris, hanya catatan di mana kolom Peran memiliki nilai Siswa yang ditampilkan.
Demikian pula, pengguna Guru hanya akan memiliki akses ke catatan di mana kolom Peran memiliki nilai Guru. Jalankan skrip berikut untuk memverifikasi ini:
EXECUTE AS USER ='Guru';Gunakan UniversitySELECT * FROM Persons; -- Semua CatatanREVERT;GODi output, Anda akan merekam berikut:
Akhirnya, dalam predikat filter kami, kami menerapkan logika bahwa Prinsipal pengguna dapat mengakses semua catatan. Mari kita verifikasi ini dengan menjalankan kueri berikut:
EXECUTE AS USER ='Principal';Gunakan UniversitySELECT * FROM Persons; -- Semua CatatanREVERT;GOPada output, Anda akan melihat semua record seperti yang ditunjukkan di bawah ini:
Kesimpulan
Fitur keamanan tingkat baris sangat berguna saat Anda ingin pengguna memiliki akses yang bagus ke data tertentu. Namun, fitur keamanan tingkat baris melibatkan fungsi bernilai tabel sebaris, yang dapat menyebabkan kinerja Anda menurun.
Sebagai aturan praktis, jika Anda berencana untuk menggunakan klausa WHERE sederhana dalam fungsi predikat, kinerja Anda tidak akan terpengaruh. Di sisi lain, pernyataan gabungan kompleks yang melibatkan tabel pencarian harus dihindari ketika Anda telah menerapkan keamanan tingkat baris.