Klausa EXECUTE AS (Transact-SQL)
Berlaku untuk: SQL ServerAzure SQL Database Azure SQL Managed Instance
Di SQL Server Anda dapat menentukan konteks eksekusi modul yang ditentukan pengguna berikut: fungsi (kecuali fungsi bernilai tabel sebaris), prosedur, antrean, dan pemicu.
Dengan menentukan konteks di mana modul dijalankan, Anda dapat mengontrol akun pengguna mana yang digunakan Mesin Database untuk memvalidasi izin pada objek yang dirujuk oleh modul. Ini memberikan fleksibilitas dan kontrol tambahan dalam mengelola izin di seluruh rantai objek yang ada antara modul yang ditentukan pengguna dan objek yang direferensikan oleh modul tersebut. Izin harus diberikan kepada pengguna hanya pada modul itu sendiri, tanpa harus memberi mereka izin eksplisit pada objek yang direferensikan. Hanya pengguna yang menjalankan modul sebagaimana harus memiliki izin pada objek yang diakses oleh modul.
Sintaks
Bagian ini menjelaskan sintaks SQL Server untuk EXECUTE AS
.
Fungsi (kecuali fungsi bernilai tabel sebaris), prosedur tersimpan, dan pemicu DML:
{ EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' }
Pemicu DDL dengan cakupan database:
{ EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' }
Pemicu DDL dengan cakupan server dan pemicu masuk:
{ EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' }
Antrean:
{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
Argumen
PEMANGGIL
Menentukan pernyataan di dalam modul dijalankan dalam konteks pemanggil modul. Pengguna yang menjalankan modul harus memiliki izin yang sesuai tidak hanya pada modul itu sendiri, tetapi juga pada objek database apa pun yang dirujuk oleh modul.
CALLER
adalah default untuk semua modul kecuali antrean, dan sama dengan perilaku SQL Server 2005 (9.x).
CALLER
tidak dapat ditentukan dalam pernyataan CREATE QUEUE
atau ALTER QUEUE
.
DIRI
EXECUTE AS SELF
setara dengan EXECUTE AS <user_name>
, di mana pengguna yang ditentukan adalah orang yang membuat atau mengubah modul. ID pengguna aktual orang yang membuat atau memodifikasi modul disimpan di execute_as_principal_id
kolom dalam sys.sql_modules
tampilan katalog atau sys.service_queues
.
SELF
adalah default untuk antrean.
Catatan
Untuk mengubah ID execute_as_principal_id
pengguna kolom dalam sys.service_queues
tampilan katalog, Anda harus secara eksplisit menentukan EXECUTE AS
pengaturan dalam ALTER QUEUE
pernyataan.
PEMILIK
Menentukan bahwa pernyataan di dalam modul dijalankan dalam konteks pemilik modul saat ini. Jika modul tidak memiliki pemilik tertentu, pemilik skema modul akan digunakan. OWNER
tidak dapat ditentukan untuk pemicu DDL atau masuk.
Penting
OWNER
harus memetakan ke akun singleton, dan tidak dapat menjadi peran atau grup.
'user_name'
Menentukan pernyataan di dalam modul yang dijalankan dalam konteks pengguna yang ditentukan dalam user_name. Izin untuk objek apa pun dalam modul diverifikasi terhadap user_name. user_name tidak dapat ditentukan untuk pemicu DDL dengan cakupan server atau pemicu masuk. Gunakan login_name sebagai gantinya.
user_name harus ada di database saat ini dan harus berupa akun singleton. user_name tidak boleh menjadi grup, peran, sertifikat, kunci, atau akun bawaan, seperti NT AUTHORITY\LocalService
, , NT AUTHORITY\NetworkService
atau NT AUTHORITY\LocalSystem
.
ID pengguna konteks eksekusi disimpan dalam metadata dan dapat dilihat di execute_as_principal_id
kolom dalam sys.sql_modules
tampilan katalog atau sys.assembly_modules
.
'login_name'
Menentukan pernyataan di dalam modul yang dijalankan dalam konteks login SQL Server yang ditentukan dalam login_name. Izin untuk objek apa pun dalam modul diverifikasi terhadap login_name. login_name hanya dapat ditentukan untuk pemicu DDL dengan cakupan server atau pemicu masuk.
login_name tidak boleh menjadi grup, peran, sertifikat, kunci, atau akun bawaan, seperti NT AUTHORITY\LocalService
, , NT AUTHORITY\NetworkService
atau NT AUTHORITY\LocalSystem
.
Keterangan
Bagaimana Mesin Database mengevaluasi izin pada objek yang dirujuk dalam modul bergantung pada rantai kepemilikan yang ada antara objek panggilan dan objek yang dirujuk. Dalam versi SQL Server sebelumnya, penautan kepemilikan adalah satu-satunya metode yang tersedia untuk menghindari harus memberikan akses pengguna panggilan ke semua objek yang dirujuk.
Penautan kepemilikan memiliki batasan berikut:
- Hanya berlaku untuk pernyataan DML:
SELECT
, ,INSERT
UPDATE
, danDELETE
. - Pemilik panggilan dan objek yang dipanggil harus sama.
- Tidak berlaku untuk kueri dinamis di dalam modul.
Terlepas dari konteks eksekusi yang ditentukan dalam modul, tindakan berikut selalu berlaku:
Ketika modul dijalankan, Mesin Database terlebih dahulu memverifikasi bahwa pengguna yang menjalankan modul memiliki
EXECUTE
izin pada modul.Aturan penautan kepemilikan terus berlaku. Ini berarti jika pemilik panggilan dan objek yang dipanggil sama, tidak ada izin yang diperiksa pada objek yang mendasar.
Ketika pengguna menjalankan modul yang telah ditentukan untuk dijalankan dalam konteks selain CALLER
, izin pengguna untuk menjalankan modul dicentang, tetapi izin tambahan memeriksa objek yang diakses oleh modul dilakukan terhadap akun pengguna yang ditentukan dalam EXECUTE AS
klausul. Pengguna yang menjalankan modul, berlaku, meniru pengguna yang ditentukan.
Konteks yang ditentukan dalam EXECUTE AS
klausul modul hanya berlaku selama durasi eksekusi modul. Konteks kembali ke pemanggil saat eksekusi modul selesai.
Tentukan nama pengguna atau login
Login pengguna atau server database yang ditentukan dalam EXECUTE AS
klausul modul tidak dapat dihilangkan hingga modul dimodifikasi untuk dijalankan di bawah konteks lain.
Nama pengguna atau login yang ditentukan dalam EXECUTE AS
klausul harus ada sebagai prinsipal di sys.database_principals
atau sys.server_principals
, masing-masing, atau operasi buat atau ubah modul gagal. Selain itu, pengguna yang membuat atau mengubah modul harus memiliki izin IMPERSONATE pada prinsipal.
Jika pengguna memiliki akses implisit ke database atau instans SQL Server melalui keanggotaan grup Windows, pengguna yang ditentukan dalam EXECUTE AS
klausul dibuat secara implisit ketika modul dibuat ketika salah satu persyaratan berikut ada:
- Pengguna atau login yang ditentukan adalah anggota peran server tetap sysadmin .
- Pengguna yang membuat modul memiliki izin untuk membuat prinsipal.
Ketika tidak satu pun dari persyaratan ini terpenuhi, operasi buat modul gagal.
Penting
Jika layanan SQL Server (MSSQLSERVER) berjalan sebagai akun lokal (layanan lokal atau akun pengguna lokal), layanan tersebut tidak akan memiliki hak istimewa untuk mendapatkan keanggotaan grup akun domain Windows yang ditentukan dalam EXECUTE AS
klausa. Ini akan menyebabkan eksekusi modul gagal.
Misalnya, asumsikan kondisi berikut:
CompanyDomain\SQLUsers
grup memiliki akses keSales
database.CompanyDomain\SqlUser1
adalah anggota danSQLUsers
oleh karena itu memiliki akses keSales
database.Pengguna yang membuat atau mengubah modul memiliki izin untuk membuat prinsipal.
Saat pernyataan berikut CREATE PROCEDURE
dijalankan, CompanyDomain\SqlUser1
secara implisit dibuat sebagai prinsipal database dalam Sales
database.
USE Sales;
GO
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT USER_NAME();
GO
Gunakan pernyataan mandiri EXECUTE AS CALLER
EXECUTE AS CALLER
Gunakan pernyataan mandiri di dalam modul untuk mengatur konteks eksekusi ke pemanggil modul.
Asumsikan prosedur tersimpan berikut dipanggil oleh SqlUser2
.
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'SqlUser1'
AS
SELECT USER_NAME(); -- Shows execution context is set to SqlUser1.
EXECUTE AS CALLER;
SELECT USER_NAME(); -- Shows execution context is set to SqlUser2, the caller of the module.
REVERT;
SELECT USER_NAME(); -- Shows execution context is set to SqlUser1.
GO
Gunakan EXECUTE AS untuk menentukan set izin kustom
Menentukan konteks eksekusi untuk modul dapat berguna saat Anda ingin menentukan set izin kustom. Misalnya, beberapa tindakan, seperti TRUNCATE TABLE
tidak memiliki izin yang dapat diberikan. Dengan menggabungkan TRUNCATE TABLE
pernyataan dalam modul dan menentukan bahwa modul dijalankan sebagai pengguna yang memiliki izin untuk mengubah tabel, Anda dapat memperluas izin untuk memotong tabel kepada pengguna yang Anda berikan EXECUTE
izin pada modul.
Untuk melihat definisi modul dengan konteks eksekusi yang ditentukan, gunakan tampilan katalog sys.sql_modules (Transact-SQL ).
Praktik terbaik
Tentukan login atau pengguna yang memiliki hak istimewa paling sedikit yang diperlukan untuk melakukan operasi yang ditentukan dalam modul. Misalnya, jangan tentukan akun pemilik database kecuali izin tersebut diperlukan.
Izin
Untuk menjalankan modul yang ditentukan dengan EXECUTE AS
, pemanggil harus memiliki EXECUTE
izin pada modul.
Untuk menjalankan modul CLR yang ditentukan dengan EXECUTE
AS yang mengakses sumber daya di database atau server lain, database atau server target harus mempercayai pengautentikasi database tempat modul berasal (database sumber).
Untuk menentukan EXECUTE AS
klausul saat membuat atau memodifikasi modul, Anda harus memiliki IMPERSONATE
izin pada prinsipal yang ditentukan dan juga izin untuk membuat modul. Anda selalu dapat meniru diri Sendiri. Ketika tidak ada konteks eksekusi yang ditentukan atau EXECUTE AS CALLER
ditentukan, IMPERSONATE
izin tidak diperlukan.
Untuk menentukan login_name atau user_name yang memiliki akses implisit ke database melalui keanggotaan grup Windows, Anda harus memiliki CONTROL
izin pada database.
Contoh
Contoh berikut membuat prosedur tersimpan dalam database AdventureWorks2022 dan menetapkan konteks eksekusi ke OWNER
.
CREATE PROCEDURE HumanResources.uspEmployeesInDepartment @DeptValue INT
WITH EXECUTE AS OWNER
AS
SET NOCOUNT ON;
SELECT e.BusinessEntityID,
c.LastName,
c.FirstName,
e.JobTitle
FROM Person.Person AS c
INNER JOIN HumanResources.Employee AS e
ON c.BusinessEntityID = e.BusinessEntityID
INNER JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.BusinessEntityID = edh.BusinessEntityID
WHERE edh.DepartmentID = @DeptValue
ORDER BY c.LastName,
c.FirstName;
GO
-- Execute the stored procedure by specifying department 5.
EXECUTE HumanResources.uspEmployeesInDepartment 5;
GO