EXECUTE AS 절(Transact-SQL)

적용 대상:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

SQL Server에서 사용자 정의 모듈인 함수(인라인 테이블 반환 함수 제외), 프로시저, 큐 및 트리거의 실행 컨텍스트를 정의할 수 있습니다.

모듈이 실행되는 컨텍스트를 지정해서 데이터베이스 엔진 사용자 계정을 제어하면 모듈에서 참조하는 개체에 대한 사용 권한을 검사할 수 있습니다. 이렇게 하면 사용자 정의 모듈 및 해당 모듈에서 참조하는 개체 사이에 있는 개체 체인에서 좀 더 유연하게 사용 권한 관리를 제어할 수 있습니다. 참조된 개체에 대한 명시적 사용 권한이 아닌 모듈 자체에 대한 사용 권한만 사용자에게 부여해야 합니다. 모듈을 실행하고 있는 사용자만이 모듈에서 액세스하는 개체에 대한 사용 권한을 가져야 합니다.

Transact-SQL 구문 표기 규칙

구문

이 섹션에서는 에 대한 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' }

참고 항목

SQL Server 2014(12.x) 및 이전 버전에 대한 Transact-SQL 구문을 보려면 이전 버전 설명서를 참조 하세요.

인수

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_idsys.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( , , INSERTUPDATEDELETE)에만 적용됩니다.
  • 호출 개체의 소유자와 호출된 개체의 소유자가 동일해야 합니다.
  • 모듈 내의 동적 쿼리에는 적용되지 않습니다.

다음 동작은 모듈에 지정된 실행 컨텍스트에 관계없이 항상 적용됩니다.

  • 모듈이 실행되면 데이터베이스 엔진 먼저 모듈을 실행하는 사용자에게 모듈 EXECUTE 에 대한 권한이 있는지 확인합니다.

  • 소유권 체인 규칙은 지속적으로 적용됩니다. 즉, 호출 개체의 소유자와 호출된 개체의 소유자가 동일한 경우 원본 개체에 대한 사용 권한을 확인하지 않습니다.

사용자가 다른 CALLER컨텍스트에서 실행하도록 지정된 모듈을 실행하면 모듈을 실행할 수 있는 사용자의 권한이 검사 모듈에서 액세스하는 개체에 대한 추가 권한 검사 절에 EXECUTE AS 지정된 사용자 계정에 대해 수행됩니다. 결과적으로 모듈을 실행하는 사용자는 지정된 사용자를 가장하게 됩니다.

모듈 절에 EXECUTE AS 지정된 컨텍스트는 모듈 실행 기간 동안에만 유효합니다. 모듈 실행이 완료되면 컨텍스트는 호출자로 되돌아갑니다.

사용자 또는 로그인 이름 지정

모듈의 절에 EXECUTE AS 지정된 데이터베이스 사용자 또는 서버 로그인은 모듈이 다른 컨텍스트에서 실행되도록 수정될 때까지 삭제할 수 없습니다.

절에 EXECUTE AS 지정된 사용자 또는 로그인 이름은 각각 보안 주체 sys.database_principalssys.server_principals존재해야 합니다. 그렇지 않으면 모듈 만들기 또는 변경 작업이 실패합니다. 또한 모듈을 만들거나 변경하는 사용자에게는 보안 주체에 대한 IMPERSONATE 권한이 있어야 합니다.

사용자가 Windows 그룹 멤버 자격을 통해 SQL Server의 데이터베이스 또는 인스턴스에 암시적으로 액세스할 수 있는 경우 다음 요구 사항 중 하나가 있을 때 모듈을 만들 때 절에 EXECUTE AS 지정된 사용자가 암시적으로 만들어집니다.

  • 지정된 사용자 또는 로그인이 sysadmin 고정 서버 역할의 멤버입니다.
  • 모듈을 만드는 사용자에게 보안 주체를 만들 사용 권한이 권한이 있습니다.

이러한 요구 사항이 충족되지 않는 경우에는 모듈을 만들 수 없습니다.

Important

SQL Server(MSSQLSERVER) 서비스가 로컬 계정(로컬 서비스 또는 로컬 사용자 계정)으로 실행되는 경우 절에 지정된 Windows do기본 계정의 그룹 멤버 자격을 가져올 수 있는 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