Saya senang Anda menyelesaikan ini, tetapi kepemilikan rantai bukan solusi yang disarankan. Karena Anda tampaknya benar-benar khawatir tentang keamanan dan rincian hak yang terlibat, saya menambahkan balasan ini, meskipun terlambat, sebagai referensi untuk apa yang terjadi dan bagaimana menyelesaikan masalah ini.
EXECUTE AS lingkup peniruan
Klausa EXECUTE AS datang dalam dua rasa: EXECUTE AS LOGIN dan EXECUTE AS USER. EXECUTE AS LOGIN diautentikasi oleh server dan merupakan konteks peniruan yang dipercaya oleh seluruh instance SQL (lingkup server):
Saat menyamar sebagai prinsipal dengan menggunakan pernyataan EXECUTE AS LOGIN, atau dalam modul lingkup server dengan menggunakan klausa EXECUTE AS, ruang lingkup peniruannya adalah di seluruh server. Ini berarti bahwa setelah konteks beralih, sumber daya apa pun dalam server tempat login yang ditiru memiliki izin dapat diakses.
EXECUTE AS USER diautentikasi oleh database dan merupakan konteks peniruan yang hanya dipercaya oleh database tersebut (lingkup-database):
Namun, ketika menyamar sebagai prinsipal dengan menggunakan pernyataan EXECUTE AS USER, atau dalam modul lingkup-database dengan menggunakan klausa EXECUTE AS, ruang lingkup peniruan dibatasi untuk database secara default. Ini berarti bahwa referensi ke objek di luar lingkup basis data akan menghasilkan kesalahan.
Prosedur tersimpan yang memiliki klausa EXECUTE AS akan membuat konteks peniruan cakupan yang dilingkupi oleh basis data, dan dengan demikian tidak akan dapat merujuk objek di luar basis data, jika Anda tidak dapat merujuk msdb.dbo.sp_start_job
karena ada di msdb
. Ada banyak contoh lain yang tersedia, seperti mencoba mengakses ruang lingkup DMV server, mencoba menggunakan server tertaut atau mencoba untuk mengirimkan pesan Broker Layanan ke dalam basis data lain.
Memungkinkan peniruan cakupan database untuk mengakses sumber daya yang biasanya tidak diizinkan autentikator dari konteks peniruan harus dipercaya. Untuk peniruan cakupan dengan basis data, authenticator adalah basis data dbo. Ini dapat dicapai dengan dua cara yang mungkin:
- Dengan mengaktifkan properti TRUSTWORTHY pada database yang mengotentikasi konteks peniruan (mis. Database tempat klausa EXECUTE AS dikeluarkan).
- Dengan menggunakan tanda tangan kode.
Rincian ini dijelaskan dalam MSDN: Memperluas Peniruan Database dengan Menggunakan EXECUTE AS .
Ketika Anda menyelesaikan masalah melalui rantai kepemilikan silang basis data, Anda telah mengaktifkan rantai silang-db di seluruh tingkat server, yang dianggap sebagai risiko keamanan. Cara paling terkontrol, berbutir halus untuk mencapai hasil yang diinginkan adalah dengan menggunakan penandatanganan kode:
- Dalam aplikasi database buat sertifikat yang ditandatangani sendiri
- tanda tangani
dbo.StartAgentJob
dengan sertifikat ini
- jatuhkan kunci pribadi sertifikat
- ekspor sertifikat ke disk
- impor sertifikat ke
msdb
- buat pengguna turunan dari sertifikat yang diimpor di
msdb
- memberikan izin AUTHENTICATE kepada pengguna yang berasal di
msdb
Langkah-langkah ini memastikan bahwa konteks dbo.StartAgentJob
prosedur EXECUTE AS sekarang dipercaya msdb
, karena konteksnya ditandatangani oleh kepala sekolah yang memiliki izin ASLI di msdb
. Ini memecahkan setengah dari teka-teki. Setengah lainnya adalah untuk benar-benar memberikan izin EXECUTE msdb.dbo.sp_start_job
ke konteks peniruan yang sekarang tepercaya. Ada beberapa cara bagaimana ini bisa dilakukan:
- memetakan pengguna
agentProxy
pengguna yang ditiru msdb
dan memberinya izin untuk mengeksekusimsdb.dbo.sp_start_job
- memberikan izin eksekusi kepada pengguna
msdb
asli sertifikat yang diturunkan
- tambahkan tanda tangan baru ke prosedur, dapatkan pengguna untuk itu
msdb
dan berikan izin eksekusi kepada pengguna turunan ini
Opsi 1. sederhana, tetapi memiliki kelemahan besar: agentProxy
pengguna sekarang dapat melakukan atas msdb.dbo.sp_start_job
kehendaknya sendiri, ia benar-benar diberikan akses ke msdb
dan memiliki izin eksekusi.
Opsi 3 benar secara positif, tetapi saya merasa tidak perlu berlebihan.
Jadi pilihan saya adalah Opsi 2: berikan izin EXECUTE msdb.dbo.sp_start_job
ke pengguna yang berasal dari sertifikat yang dibuat di msdb
.
Berikut ini adalah SQL yang sesuai:
use [<appdb>];
go
create certificate agentProxy
ENCRYPTION BY PASSWORD = 'pGFD4bb925DGvbd2439587y'
with subject = 'agentProxy'
, start_date='01/01/2009';
go
ADD SIGNATURE TO OBJECT::[StartAgentJob]
BY CERTIFICATE [agentProxy]
WITH PASSWORD = 'pGFD4bb925DGvbd2439587y';
go
alter certificate [agentProxy]
remove private key;
go
backup certificate [agentProxy]
to file='c:\temp\agentProxy.cer';
go
use msdb
go
create certificate [agentProxy]
from file='c:\temp\agentProxy.cer';
go
create user [agentProxyAuthenticator]
from certificate [agentProxy];
go
grant authenticate to [agentProxyAuthenticator];
grant execute on msdb.dbo.sp_start_job to [agentProxyAuthenticator];
go
use [<appdb>];
go
exec dbo.StartAgentJob;
go
Blog saya memiliki beberapa artikel yang membahas topik ini, ditulis dalam konteks prosedur yang diaktifkan oleh Broker Layanan (karena memerlukan klausa EXECUTE AS):
BTW, jika Anda mencoba menguji skrip saya dan Anda tinggal di belahan bumi timur, atau di musim panas Inggris, pasti baca artikel terakhir yang saya tautkan sebelum pengujian.