MSSQLSERVER_15517
적용 대상: SQL Server
세부 정보
attribute | 값 |
---|---|
제품 이름 | SQL Server |
이벤트 ID | 15517 |
이벤트 원본 | MSSQLSERVER |
구성 요소 | SQLEngine |
심볼 이름 | SEC_CANNOTEXECUTEASUSER |
메시지 텍스트 | 보안 주체 "보안 주체"가 없거나, 이 유형의 보안 주체를 가장할 수 없거나, 권한이 없으므로 데이터베이스 보안 주체로 실행할 수 없습니다. |
설명
이 오류는 일반적으로 Microsoft SQL Server가 문을 사용하여 EXECUTE AS
사용자 문 또는 모듈에 지정된 보안 주체의 실행 컨텍스트에 대한 정보를 가져올 수 없기 때문에 발생합니다.
SQL Server 인스턴스에서 데이터베이스를 테이블의 해당 데이터베이스 행 sys.databases
및 데이터베이스 내 테이블의 사용자 항목 sys.database_principals
에 대한 dbo
데이터베이스 소유자로 만들 때 로그인 정보 SID(보안 식별자)가 자동으로 저장됩니다.
dbo 사용자에 대해 저장된 SID 항목이 유효한 경우 절을 사용하는 EXECUTE AS OWNER
문 또는 모듈이 예상대로 작동합니다.
참고 항목
이 문제는 문에 EXECUTE AS
사용되고 데이터베이스가 복원되는 서버에 존재하지 않는 보안 주체에 대해 발생할 수 있습니다.
이 문제가 발생할 수 있는 몇 가지 일반적인 시나리오는 다음과 같습니다.
백업이 원래 수행된 동일한 서버 인스턴스에서 데이터베이스를 복원하지만 데이터베이스를 만든 SQL Server 보안 주체는 어떤 이유로 더 이상 유효하지 않습니다. 예시:
- SQL Server 인증 로그인이 제거되었습니다.
- Windows 인증 로그인은 직원이 회사를 떠났기 때문에 Active Directory의 유효한 사용자에 대해 더 이상 사용할 수 없습니다.
백업이 원래 수행된 인스턴스와 다른 서버의 데이터베이스를 복원하지만 데이터베이스를 만든 SQL Server 보안 주체는 새 서버에서 유효한 보안 주체가 아닙니다.
- 사용자가 SQL Server 로그인인 경우 보안 주체가 대상 또는 대상 서버에 있을 수 있지만 값은
sid
다릅니다. - 사용자가 Windows 로그인인 경우 대상 서버에 Windows 로그인이 없거나 더 이상 유효하지 않습니다.
- 사용자가 SQL Server 로그인인 경우 보안 주체가 대상 또는 대상 서버에 있을 수 있지만 값은
저장 프로시저, 함수 또는 트리거를 실행하는 사용자 또는 애플리케이션에는 문에 EXECUTE AS
지정된 보안 주체를 가장하는 데 필요한 권한이 없습니다.
사용자 작업
기존 보안 주체의 이름을 사용하거나 필요한 사용자에게 해당 보안 주체에 대한 IMPERSONATE 권한을 부여합니다.
잘못된 dbo 사용자 오류로 인해 발생하는 문제를 해결하려면 다음 명령을 실행하여 서버의 유효한 로그인으로 값을 변경 dbo_User
합니다.
ALTER AUTHORIZATION ON DATABASE:: DBName TO [NewLogin]
예제 시나리오
두 개의 임시 보안 주체를 만듭니다.
CREATE LOGIN login1 WITH PASSWORD = 'J345#$)thb'; CREATE LOGIN login2 WITH PASSWORD = 'Uor80$23b';
이러한 로그인을 sysadmin 역할에 추가합니다(데모 전용).
를 사용하여
login1
SQL Server 인스턴스에 로그인합니다.다음 스크립트를 실행하여 명명
testexec
된 데모 데이터베이스 및 저장 프로시저를 만듭니다.CREATE DATABASE Demodb_15517 GO USE Demodb_15517 GO CREATE procedure [dbo].[testexec] WITH EXECUTE AS owner AS SELECT @@VERSION GO EXEC dbo.testexec GO
다음 쿼리를 실행하고 값이
sid
유효한 로그인으로 확인되는지 확인합니다.쿼리 1: sys.databases의 값 값을
Owner_Name
확인합니다.SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName FROM sys.databases WHERE NAME = N'Demodb_15517';
Database_Name owner_sid OwnerName --------------------- -------------------------------------- ---------------------------- Demodb_15517 0xDB79ED7B6731CF4E8DC7DF02871E3E36 login1
쿼리 2: 데모 데이터베이스 내의
sys.database_principals
테이블 값을 확인Owner_Name
합니다.SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name SID ------------- ------------------------------------------------ login1 0xDB79ED7B6731CF4E8DC7DF02871E3E36
다음 스크립트와 유사한 쿼리를 사용하여 데모 데이터베이스를 백업합니다.
BACKUP DATABASE [Demodb_15517] TO DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH NOFORMAT, NOINIT, NAME = N'Demodb_15517 Full backup', SKIP, EWIND, NOUNLOAD, STATS = 10 GO
데모 데이터베이스를 삭제하고
login1
다음을 수행합니다.DROP DATABASE demodb_15517 GO DROP login login1 GO
로 SQL Server
login2
에 로그인합니다.다음 스크립트와 유사한 문을 사용하여 백업에서 데모 데이터베이스를 복원합니다.
USE [master] RESTORE DATABASE [Demodb_15517] FROM DISK = N'C:\SQLBackups\Demodb_15517.bak' WITH FILE = 1, MOVE N'Demodb_15517' TO N'C:\SQLBackups\Demodb_15517.mdf', MOVE N'Demodb_15517_log' TO N'C:\SQLBackups\\Demodb_155172_log.ldf', NOUNLOAD, STATS = 5 GO
쿼리 1 및 쿼리 2를 다시 실행합니다.
쿼리 1에서 값의
Owner_Name
값을 확인합니다sys.databases
. 이제 값이 반영됩니다.login2
SELECT NAME AS Database_Name, owner_sid, SUSER_SNAME(owner_sid) AS OwnerName FROM sys.databases WHERE NAME = N'Demodb_15517';
Database_Name owner_sid OwnerName -------------- --------------------------------------- --------------------- Demodb_15517 0xD63086DD7277BC4EB88013D359AF73A6 login2
쿼리 2에서 데모 데이터베이스 내의
Owner_Name
sys.database_principals
테이블 값 값을 확인합니다. 이제 값이 반영됩니다.NULL
SELECT SUSER_SNAME(sid) AS Owner_Name, sid FROM Demodb_15517.sys.database_principals WHERE NAME = N'dbo';
Owner_Name sid ------------------ ----------------------------------------------- NULL 0xDB79ED7B6731CF4E8DC7DF02871E3E36
저장 프로시저를
testexec
실행합니다. 이제 "15517" 오류 메시지가 표시됩니다.USE Demodb_15517 GO EXEC dbo.testexec GO
Msg 15517, Level 16, State 1, Procedure dbo.testexec, Line 0 [Batch Start Line 19] Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
오류를 해결하려면 다음 명령을 사용하여 dbo를 유효한 사용자(
login2
)로 변경합니다.ALTER AUTHORIZATION ON DATABASE:: Demodb_15517 TO [login2]
쿼리 2를 다시 실행하고 dbo 사용자가 이제 login2 사용자로 확인되는지 확인합니다.
Owner_Name SID ---------------------------------------------------------------- login2 0xD63086DD7277BC4EB88013D359AF73A6
다시 시도하여 테스트 저장 프로시저를 실행합니다. 이제 성공적으로 실행됩니다.
USE Demodb_15517 GO EXEC dbo.testexec GO
/* -- You get an output that resembles the following --------------------------------------------------------------------------------------------------------- Microsoft SQL Server 2019 (RTM-CU16-GDR) (KB5014353) - 15.0.4236.7 (X64) May 29 2022 15:55:47 Copyright (C) 2019 Microsoft Corporation Express Edition (64-bit) on Windows 10 Enterprise 10.0 <X64> (Build 22621: ) (Hypervisor) */