Menjalankan Prosedur Disimpan yang mengakses contoh SQL lain

8

Saya minta maaf jika pertanyaan ini mengulangi pertanyaan lain yang sudah diajukan. Saya telah mencari selama berjam-jam dan belum menemukan satu yang cocok dengan situasi saya.

Hasil yang diinginkan

Seorang pengguna yang menggunakan otentikasi SQL telah menjalankan izin untuk Database1 pada Server1 (contoh default) dan hanya itu. Pengguna menjalankan prosedur tersimpan yang, sebagai bagian dari prosesnya, mengakses Database 2 di Server1 \ Instance2. Saya ingin ini aman dan sederhana (keduanya penting).

Info lebih lanjut

Kredensial windows saya memiliki akses ke kedua instance (yang berada di server yang sama). Oleh karena itu, saya dapat menjalankan prosedur tersimpan di bawah login saya tanpa kesulitan. Namun, saya tidak ingin memberikan tingkat akses kepada pengguna. Saya juga perlu menggunakan login SQL karena pengguna tidak akan berada di domain.

Apa yang saya inginkan adalah memberikan prosedur yang tersimpan tingkat akses saya hanya untuk prosedur itu. Karena saya seorang sysadmin, itu akan memberi pengguna semua yang mereka butuhkan untuk prosedur itu. Jika saya berhasil, saya mungkin akan membuat akun hanya untuk tujuan itu daripada menggunakan milik saya, tetapi bagaimanapun juga itu akan aman karena saya mengontrol apa yang dilakukan oleh proc yang disimpan.

Saya mencoba meletakkan pernyataan "DENGAN EXECUTE AS" di proc saya yang tersimpan tetapi saya tidak bisa mendapatkannya untuk mengambil informasi login windows saya. Ketika saya memasukkannya, saya akan mendapatkan kesalahan berikut setelah mengkompilasi proc yang disimpan:

Tidak dapat mengeksekusi sebagai pengguna 'domain \ jdoe', karena tidak ada atau Anda tidak memiliki izin.

Pengguna adalah sysadmin di kedua server, seperti yang saya katakan, jadi saya tidak yakin apa lagi yang dibutuhkan.

Saya telah melihat yang berikut ini:

  • TRUSTED - Saya lebih suka tidak mengekspos database saya dan ini terlihat menakutkan
  • Server yang ditautkan - Saya tidak ingin memberikan izin tambahan. Saya tidak percaya database lain untuk memiliki akses ke database saya dan saya tidak percaya database saya untuk memiliki akses ke semua database lain.
  • Sertifikat - Ini sepertinya rumit dan sulit. Kecuali saya dapat menemukan cara yang sangat sederhana untuk melakukan ini dan memeliharanya, saya tidak yakin itu sepadan dengan masalahnya.
  • Rantai kepemilikan - Sekali lagi, menakutkan. Sepertinya ini menyebabkan lebih banyak masalah keamanan ketika tujuan saya adalah untuk mencegah masalah keamanan.
  • Pengguna yang dicerminkan - Saya bahkan telah membuat pengguna yang sama (berbeda SID) pada contoh server lain dan memberikannya kata sandi yang sama. Tidak pergi.

Saya merasa kehilangan sesuatu yang jelas tapi saya tidak yakin apa itu. Karena saya telah membenturkan kepala ke dinding sepanjang hari ini, saya mungkin terlalu dekat untuk melihatnya. Saya akan sangat menghargainya jika seseorang di sini dapat membantu saya atau mengarahkan saya ke arah yang benar. Saya akan mengatakan bahwa saya telah membaca banyak artikel MSDN (anak laki-laki saya benci mereka - mereka sepertinya tidak pernah memberi tahu saya apa yang ingin saya ketahui). Apa yang saya benar-benar suka adalah tutorial sederhana, mudah diikuti yang menuntun saya melalui cara melakukan ini. Singkatnya, bahkan indikasi umum tentang arah yang harus saya tuju akan sangat membantu.

IAmTimCorey
sumber

Jawaban:

3

Coba gunakan EXECUTE AS LOGIN = 'DOMAIN \ username' dan lihat apakah itu berhasil.

mrdenny
sumber
Saya sudah mencobanya tetapi perintah itu tidak dirancang untuk di dalam prosedur tersimpan, jelas.
IAmTimCorey
Ini seharusnya bekerja dengan baik di dalam prosedur tersimpan. Apakah akun Anda dibuat dengan login sendiri, atau Anda mendapatkan hak melalui keanggotaan grup?
mrdenny
Akun saya memiliki login sendiri, yang memiliki hak sysadmin. Ini juga memiliki hak Admin Domain melalui keanggotaan grup, sehingga harus memberi saya semua yang saya butuhkan dan itu terjadi ketika saya logon menggunakan kredensial Windows saya. Namun, saya menemukan dua hal. Pertama, jika saya menggunakan kode Anda di atas dalam pernyataan WITH dari proc yang disimpan, itu memberi saya kesalahan sintaks. Jika saya memasukkannya ke dalam pernyataan, itu akan berfungsi di dalam satu instance tetapi tidak pada instance-silang.
IAmTimCorey
3

Lihatlah menggunakan EXECUTE AS+ Dapat Dipercaya. Anda dapat mengaturnya di mana ia dapat dipanggil dalam prosedur tersimpan selama pengguna b telah diberikan akses dan dua basis data saling percaya.

Blog orang ini harus menjawab atau memberikan semua yang Anda butuhkan. http://www.sommarskog.se/grantperm.html#EXECAScrossdb

penggunaan properti database TRUSTWORTHY untuk mengontrol akses ke sumber daya di luar ruang lingkup sumber database

http://msdn.microsoft.com/en-us/library/ms188304%28v=sql.90%29.aspx

SoftwareCarpenter
sumber
Masalah yang saya lihat adalah bahwa Trustworthy membangun hubungan saling percaya antara kedua database. Ini dapat dieksploitasi oleh sysadmin di kedua sisi. Saya tidak menginginkan ini. Saya mencoba membatasi izin yang dimiliki satu orang. Jika saya akhirnya memberikan izin lebih kepada orang lain, itu tidak akan menjadi hal yang baik. Terimakasih Meskipun.
IAmTimCorey
Perhatikan di sini bahwa pemilik perorangan tidak harus orang fisik, tetapi itu bisa berupa login umum untuk setiap basis data. Anda tidak harus memberikan seluruh database. Jika Anda tidak mempercayai sysadmin pada database lain, maka bersikeras penandatanganan sertifikat.
SoftwareCarpenter
Anda menyebutkan bahwa Anda menemukan tautan sommarskog.se/grantperm.html dalam jawaban Anda di bawah ini. Itu adalah blog yang sama yang saya posting di jawaban yang saya sarankan. "Blog orang ini harus menjawab atau memberikan semua yang Anda butuhkan. Sommarskog.se/grantperm.html#EXECAScrossdb " Mungkin Anda hanya mereferensikan ulang untuk orang lain. Saya setuju itu blog yang bagus dan baca. Semoga berhasil!
SoftwareCarpenter
Ya, maaf saya lupa mengatakan bahwa tautan itu berasal dari Anda. Itu sumber yang bagus. Terima kasih atas bantuan Anda.
IAmTimCorey
2

Setelah membaca banyak tentang topik ini dan melakukan sejumlah percobaan, saya yakin saya telah sampai pada kesimpulan tentang masalah ini. Pernyataan EXECUTE AS tidak dirancang untuk bekerja lintas contoh tanpa implikasi keamanan besar. Apa yang saya harapkan adalah cara untuk memberi tahu prosedur saya tentang identitas Windows yang ingin saya jalankan, karena identitas Windows dapat memiliki akses ke banyak sumber daya pada beberapa server. Namun, bahkan setelah bermain-main dengan sekelompok pengaturan yang berbeda, menjadi jelas bahwa saya harus melemahkan langkah-langkah keamanan lainnya untuk memungkinkan prosedur yang tersimpan meniru saya.

Tampaknya tidak ada banyak informasi di luar sana tentang prosedur lintas-contoh atau lintas-server. Saya akan membayangkan alasan untuk ini adalah karena implikasi keamanan dan kinerja melakukannya. Namun, saya percaya ada kasus di mana itu penting dan sepertinya solusi untuk melakukannya adalah rumit dan sangat khusus untuk skenario. Saya menemukan artikel bagus yang setidaknya membantu saya memahami beberapa pilihan saya. Itu tidak fokus pada akses lintas-contoh tetapi itu memberi saya petunjuk yang saya cari. Saya mendorong Anda untuk memeriksanya:

http://www.sommarskog.se/grantperm.html

Saya masih akan tertarik pada solusi lain untuk masalah ini, tetapi solusi saya sekarang adalah dua kali lipat. Pertama, jika saya benar-benar perlu mengakses dua database melalui satu prosedur tersimpan, saya harus menggunakan login Windows. Saya menghindari hal ini sedapat mungkin, karena hal itu menyebabkan masalah kinerja (penguncian multi-server, komplikasi jaringan, ketidakmampuan untuk mengoptimalkan kueri, dll.) Kedua, saya membawa data dari setiap basis data melalui panggilan terpisah, khusus basis data. Itu berarti saya membawa data kembali ke klien sebelum menggabungkannya. Ini bukan sebagai pemain atau bersih seperti yang saya inginkan, tetapi tampaknya menjadi solusi teraman.

IAmTimCorey
sumber
1

Jika Anda perlu mengakses objek database antara dua instance SQL server, saya akan merekomendasikan salah satu dari yang berikut:

  1. Membuat dan menggunakan Server Tertaut antara dua instance dengan izin yang sesuai untuk mengakses objek pada instance tujuan (jarak jauh).
  2. Gunakan SSIS dan aktifkan paket dari sumber contoh dari SQL Server. Bergantung pada versi SQL Server yang digunakan, Anda bisa memiliki pekerjaan SQL Agent (bukan jadwal untuk dijalankan, tetapi dipanggil oleh prosedur tersimpan) atau menggunakan SSISDB untuk memanggil paket SSIS yang akan mengakses objek database pada instance jarak jauh.
  3. Pindahkan logika ke lapisan tengah (atau sisi aplikasi klien)
  4. Buat CLR untuk mengakses objek basis data jauh Dari sini saya mungkin akan menggunakan CLR untuk mengakses server contoh jarak jauh dan menjalankan menjalankan prosedur yang tersimpan. Anda harus memberikan akun bahwa Source SQL Server Instance berjalan di bawah akses ke Remote SQL Server Instance.
Tom
sumber