EXECUTE AS 절(Transact-SQL)
적용 대상: SQL Server Azure SQL 데이터베이스 Azure SQL Managed Instance
SQL Server에서 사용자 정의 모듈인 함수(인라인 테이블 반환 함수 제외), 프로시저, 큐 및 트리거의 실행 컨텍스트를 정의할 수 있습니다.
모듈이 실행되는 컨텍스트를 지정해서 데이터베이스 엔진 사용자 계정을 제어하면 모듈에서 참조하는 개체에 대한 사용 권한을 검사할 수 있습니다. 이렇게 하면 사용자 정의 모듈 및 해당 모듈에서 참조하는 개체 사이에 있는 개체 체인에서 좀 더 유연하게 사용 권한 관리를 제어할 수 있습니다. 참조된 개체에 대한 명시적 사용 권한이 아닌 모듈 자체에 대한 사용 권한만 사용자에게 부여해야 합니다. 모듈을 실행하고 있는 사용자만이 모듈에서 액세스하는 개체에 대한 사용 권한을 가져야 합니다.
구문
이 섹션에서는 에 대한 SQL Server 구문에 대해 설명합니다 EXECUTE AS
.
함수(인라인 테이블 반환 함수 제외), 저장 프로시저 및 DML 트리거:
{ EXEC | EXECUTE } AS { CALLER | SELF | OWNER | 'user_name' }
데이터베이스 범위를 사용하는 DDL 트리거:
{ EXEC | EXECUTE } AS { CALLER | SELF | 'user_name' }
서버 범위 및 로그온 트리거를 사용하는 DDL 트리거:
{ EXEC | EXECUTE } AS { CALLER | SELF | 'login_name' }
큐:
{ EXEC | EXECUTE } AS { SELF | OWNER | 'user_name' }
인수
CALLER
모듈 내부의 문이 모듈 호출자의 컨텍스트에서 실행되도록 지정합니다. 모듈을 실행하는 사용자는 모듈 자체에 대한 알맞은 사용 권한뿐만 아니라 모듈에서 참조하는 모든 데이터베이스 개체에 대한 사용 권한도 갖고 있어야 합니다.
CALLER
는 큐를 제외한 모든 모듈의 기본값이며 SQL Server 2005(9.x) 동작과 동일합니다.
CALLER
또는 ALTER QUEUE
문에 CREATE QUEUE
지정할 수 없습니다.
SELF
EXECUTE AS SELF
는 지정된 사용자가 모듈을 만들거나 변경하는 사용자인 경우와 동일합니다 EXECUTE AS <user_name>
. 모듈을 만들거나 수정하는 사람의 실제 사용자 ID는 또는 sys.service_queues
카탈로그 뷰의 execute_as_principal_id
열에 sys.sql_modules
저장됩니다.
SELF
는 큐의 기본값입니다.
참고 항목
카탈로그 뷰에서 열의 사용자 ID를 execute_as_principal_id
sys.service_queues
변경하려면 문에서 ALTER QUEUE
설정을 명시적으로 지정 EXECUTE AS
해야 합니다.
OWNER
모듈 내의 문이 모듈의 현재 소유자 컨텍스트에서 실행되도록 지정합니다. 모듈에 지정된 소유자가 없는 경우 모듈의 스키마 소유자가 사용됩니다. OWNER
DDL 또는 로그온 트리거에 대해 지정할 수 없습니다.
Important
OWNER
는 싱글톤 계정에 매핑되어야 하며 역할 또는 그룹이 될 수 없습니다.
'user_name'
모듈 내부의 문이 user_name에 지정된 사용자의 컨텍스트에서 실행되도록 지정합니다. 모듈 내의 모든 개체에 대한 사용 권한은 user_name과 비교 검증됩니다. 서버 범위 또는 로그온 트리거가 있는 DDL 트리거에는 user_name 지정할 수 없습니다. 대신 login_name을 사용합니다.
user_name은 현재 데이터베이스에 있어야 하며 단일 계정이어야 합니다. user_name 그룹, 역할, 인증서, 키 또는 기본 제공 계정(예: NT AUTHORITY\LocalService
, NT AUTHORITY\NetworkService
또는 NT AUTHORITY\LocalSystem
)일 수 없습니다.
실행 컨텍스트의 사용자 ID는 메타데이터에 저장되며 또는 sys.assembly_modules
카탈로그 뷰의 execute_as_principal_id
열에서 sys.sql_modules
볼 수 있습니다.
'login_name'
모듈 내부의 문이 login_name에 지정된 SQL Server 로그인의 컨텍스트에서 실행되도록 지정합니다. 모듈 내의 모든 개체에 대한 사용 권한은 login_name과 비교 검증됩니다. login_name은 서버 범위의 DDL 트리거 또는 로그온 트리거에만 지정할 수 있습니다.
login_name 그룹, 역할, 인증서, 키 또는 기본 제공 계정(예: NT AUTHORITY\LocalService
, NT AUTHORITY\NetworkService
또는 NT AUTHORITY\LocalSystem
)일 수 없습니다.
설명
데이터베이스 엔진에서 모듈이 참조하는 개체에 대한 사용 권한을 평가하는 방법은 호출 개체와 참조된 개체 간에 존재하는 소유권 체인에 따라 다릅니다. 이전 버전의 SQL Server에서 호출 사용자에게 참조된 모든 개체에 대한 액세스 권한을 부여하지 않도록 하는 유일한 방법은 소유권 체인이었습니다.
소유권 체인에는 다음과 같은 제한 사항이 있습니다.
- DML 문
SELECT
( , ,INSERT
UPDATE
및DELETE
)에만 적용됩니다. - 호출 개체의 소유자와 호출된 개체의 소유자가 동일해야 합니다.
- 모듈 내의 동적 쿼리에는 적용되지 않습니다.
다음 동작은 모듈에 지정된 실행 컨텍스트에 관계없이 항상 적용됩니다.
모듈이 실행되면 데이터베이스 엔진 먼저 모듈을 실행하는 사용자에게 모듈
EXECUTE
에 대한 권한이 있는지 확인합니다.소유권 체인 규칙은 지속적으로 적용됩니다. 즉, 호출 개체의 소유자와 호출된 개체의 소유자가 동일한 경우 원본 개체에 대한 사용 권한을 확인하지 않습니다.
사용자가 다른 CALLER
컨텍스트에서 실행하도록 지정된 모듈을 실행하면 모듈을 실행할 수 있는 사용자의 권한이 선택되지만, 모듈에서 액세스하는 개체에 대한 추가 권한 검사는 절에 EXECUTE AS
지정된 사용자 계정에 대해 수행됩니다. 결과적으로 모듈을 실행하는 사용자는 지정된 사용자를 가장하게 됩니다.
모듈 절에 EXECUTE AS
지정된 컨텍스트는 모듈 실행 기간 동안에만 유효합니다. 모듈 실행이 완료되면 컨텍스트는 호출자로 되돌아갑니다.
사용자 또는 로그인 이름 지정
모듈의 절에 EXECUTE AS
지정된 데이터베이스 사용자 또는 서버 로그인은 모듈이 다른 컨텍스트에서 실행되도록 수정될 때까지 삭제할 수 없습니다.
절에 EXECUTE AS
지정된 사용자 또는 로그인 이름은 각각 보안 주체 sys.database_principals
로 sys.server_principals
존재해야 합니다. 그렇지 않으면 모듈 만들기 또는 변경 작업이 실패합니다. 또한 모듈을 만들거나 변경하는 사용자에게는 보안 주체에 대한 IMPERSONATE 권한이 있어야 합니다.
사용자가 Windows 그룹 멤버 자격을 통해 SQL Server의 데이터베이스 또는 인스턴스에 암시적으로 액세스할 수 있는 경우 다음 요구 사항 중 하나가 있을 때 모듈을 만들 때 절에 EXECUTE AS
지정된 사용자가 암시적으로 만들어집니다.
- 지정된 사용자 또는 로그인이 sysadmin 고정 서버 역할의 멤버입니다.
- 모듈을 만드는 사용자에게 보안 주체를 만들 사용 권한이 권한이 있습니다.
이러한 요구 사항이 충족되지 않는 경우에는 모듈을 만들 수 없습니다.
Important
SQL Server(MSSQLSERVER) 서비스가 로컬 계정(로컬 서비스 또는 로컬 사용자 계정)으로 실행되는 경우 절에 지정된 Windows 도메인 계정의 그룹 멤버 자격을 가져올 수 있는 EXECUTE AS
권한이 없습니다. 따라서 모듈 실행이 실패하게 됩니다.
예를 들어 다음과 같은 조건을 가정해 보세요.
CompanyDomain\SQLUsers
그룹은 데이터베이스에 액세스할 수 있습니다Sales
.CompanyDomain\SqlUser1
는 멤버SQLUsers
이므로 데이터베이스에 액세스할 수 있습니다Sales
.모듈을 만들거나 변경하는 사용자에게 보안 주체를 만들 사용 권한이 있습니다.
다음 CREATE PROCEDURE
문을 실행하면 CompanyDomain\SqlUser1
데이터베이스에서 Sales
이 데이터베이스 보안 주체로 암시적으로 생성됩니다.
USE Sales;
GO
CREATE PROCEDURE dbo.usp_Demo
WITH EXECUTE AS 'CompanyDomain\SqlUser1'
AS
SELECT USER_NAME();
GO
EXECUTE AS CALLER 독립 실행형 문 사용
모듈 내의 EXECUTE AS CALLER
독립 실행형 문을 사용하여 실행 컨텍스트를 모듈의 호출자에게 설정합니다.
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
EXECUTE AS를 사용하여 사용자 지정 권한 집합 정의
사용자 지정 권한 집합을 정의하려는 경우 모듈에 대한 실행 컨텍스트를 지정하는 것이 유용할 수 있습니다. 예를 들어 부여할 수 있는 권한이 없는 등의 TRUNCATE TABLE
일부 작업이 있습니다. 모듈 내에 문을 통합 TRUNCATE TABLE
하고 모듈이 테이블을 변경할 수 있는 권한이 있는 사용자로 실행되도록 지정하면 해당 모듈에 대한 사용 권한을 부여 EXECUTE
한 사용자에게 테이블을 자르는 권한을 확장할 수 있습니다.
지정된 실행 컨텍스트가 있는 모듈 정의를 보려면 sys.sql_modules (Transact-SQL) 카탈로그 뷰를 사용합니다.
모범 사례
모듈에 정의된 작업을 수행하는 데 필요한 최소한의 권한이 있는 로그인이나 사용자를 지정합니다. 예를 들어 해당 권한이 필요하지 않으면 데이터베이스 소유자 계정을 지정하지 마세요.
사용 권한
지정된 EXECUTE AS
모듈을 실행하려면 호출자에게 모듈에 대한 권한이 있어야 합니다 EXECUTE
.
다른 데이터베이스 또는 서버의 리소스에 액세스하는 AS로 EXECUTE
지정된 CLR 모듈을 실행하려면 대상 데이터베이스 또는 서버가 모듈이 시작된 데이터베이스의 인증자(원본 데이터베이스)를 신뢰해야 합니다.
모듈을 EXECUTE AS
만들거나 수정할 때 절을 지정하려면 지정된 보안 주체에 대한 사용 권한과 모듈을 만들 수 있는 권한도 있어야 합니다 IMPERSONATE
. 사용자는 항상 자신을 가장할 수 있습니다. 실행 컨텍스트가 지정되거나 EXECUTE AS CALLER
지정되지 IMPERSONATE
않은 경우 권한이 필요하지 않습니다.
Windows 그룹 멤버 자격을 통해 데이터베이스에 암시적으로 액세스할 수 있는 login_name 또는 user_name 지정하려면 데이터베이스에 대한 권한이 있어야 합니다CONTROL
.
예제
다음 예제에서는 AdventureWorks2022 데이터베이스에 저장 프로시저를 만들고 실행 컨텍스트를 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