SQL Server 2019 - 服务器主体“sa”无法在当前安全上下文下访问数据库“DB_NAME”

Ade*_*irP 9 sql-server database-security sql-server-2019

我编写了以下存储过程:

CREATE PROCEDURE dbo.usp_DEMO 
    @LOGINSQL VARCHAR(30), 
    @DBNAME VARCHAR(40) 
WITH EXECUTE AS owner
AS 
    DECLARE @SQL NVARCHAR(1000) 
    SET @SQL = 'USE' 
    SET @SQL = @SQL + ' ' + @DBNAME + ' ' + ' CREATE USER ' + ' ' 
               + @LOGINSQL + ' ' + ' FOR LOGIN ' + ' ' + @LOGINSQL + ' ' 
               + ' ALTER ROLE [DB_OWNER] ADD MEMBER ' + ' ' 
               + @LOGINSQL 
    EXEC sp_executesql @SQL
Run Code Online (Sandbox Code Playgroud)

像这样运行:

use master
go
exec usp_DEMO '<LOGIN>','<DATABASE>'
Run Code Online (Sandbox Code Playgroud)

我在 SQL Server 2019 STD Edition (RTM-CU6) (KB4563110) 中运行Master并收到以下错误:

消息 916,级别 14,状态 2,第 14
行 服务器主体“<OWNER_LOGIN>”无法访问当前安全上下文下的数据库“<DB_NAME>”。

这个想法是使用存储过程将登录映射到数据库并赋予db_owner角色。

知道如何解决该错误吗?

vvv*_*v4d 6

检查目标数据库所有者,如果数据库所有者不是sa或者TRUSTWORTHY目标数据库的属性为OFF,您将收到“服务器主体“sa”无法在当前安全上下文下访问数据库“DB_NAME””错误通过EXECUTE AS在存储过程中使用来模拟 SA 时:

https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/ms188304(v=sql.105)?redirectedfrom=MSDN

当使用 EXECUTE AS USER 语句模拟主体时,或者在数据库范围的模块中使用 EXECUTE AS 子句模拟主体时,默认情况下模拟的范围仅限于数据库。这意味着对数据库范围之外的对象的引用将返回错误。

选项解决了错误“服务器主体“sa”无法访问当前安全上下文下的数据库“DB_NAME””

注意:在下面的选项中,将{{TargetDb}}替换为实际的 DB_NAME

  1. 将目标数据库所有者更改为sa
USE {{TargetDb}} 
sp_changedbowner 'sa'
Run Code Online (Sandbox Code Playgroud)
  1. 或者打开TRUSTWORTHY目标数据库中的属性:
ALTER DATABASE {{TargetDb}} SET TRUSTWORTHY ON
Run Code Online (Sandbox Code Playgroud)


Mar*_*peu 1

去除WITH EXECUTE AS owner