Klausa EXECUTE AS (Transact-SQL)

Berlaku untuk:SQL ServerAzure SQL DatabaseAzure 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.

Konvensi sintaks transact-SQL

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' }

Catatan

Untuk melihat sintaks Transact-SQL untuk SQL Server 2014 (12.x) dan versi yang lebih lama, lihat Dokumentasi versi sebelumnya.

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\NetworkServiceatau 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\NetworkServiceatau 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, , INSERTUPDATE, dan DELETE.
  • 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 ke Sales database.

  • CompanyDomain\SqlUser1 adalah anggota dan SQLUsers oleh karena itu memiliki akses ke Sales 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