Sql-Server

為使用者 SQL Server 創建同義詞錯誤

  • August 10, 2019

我有一個使用者有權在我的 sql server 2016 數據庫中創建同義詞。該使用者還具有數據讀取器權限。當使用者嘗試創建同義詞時,如下所示。

USE [DEMODB] GO CREATE SYNONYM [dbo].[MYSYN] FOR [SERVER01].[DEMODB].[dbo].[CHILD] GO 使用者收到以下錯誤消息。 The specified schema name "dbo" either does not exist or you do not have permission to use it.

我檢查了登錄/使用者設置。並且登錄屬於公共伺服器角色,使用者被映射到預設模式為的數據庫

$$ dbo $$ 並且還為該使用者授予該數據庫的創建同義詞權限,如前所述。

我怎樣才能解決這個問題。

Microsoft 的文件中所述CREATE SCHEMA

“要在給定架構中創建同義詞,使用者必須擁有 CREATE SYNONYM 權限,並且要麼擁有架構,要麼擁有 ALTER SCHEMA 權限。”

使用者不僅需要CREATE SYNONYM語句權限,還需要ALTER模式權限才能創建同義詞。應謹慎授予ALTER對模式的權限,尤其是,以遵循最小權限的安全原則。dbo如果使用者在他們自己的模式中或在具有所有者的模式中創建同義詞,而不是dbo為了使使用者被沙箱化到該模式中,那會更好(也更容易) ALTER

如果最低權限使用者必須在dbo架構中創建同義詞,請考慮將CREATE SYNONYMDDL 封裝在儲存過程中並使用模組簽名來提升權限。這樣,對 proc 具有執行權限的使用者可以在dbo模式中創建同義詞,但僅限於儲存過程執行的功能。下面是這種技術的一個例子。

CREATE OR ALTER PROC dbo.CreateSynonym
     @SynonymSchemaName sysname
   , @SynonymName sysname
   , @SynonymForServerName sysname
   , @SynonymForDatabaseName sysname
   , @SynonymForSchemaName sysname
   , @SynonymForObjectName sysname
AS
DECLARE @CreateSynonymStatement nvarchar(MAX) = N'CREATE SYNONYM ' 
   + QUOTENAME(@SynonymSchemaName)
   + N'.'
   + QUOTENAME(@SynonymName)
   + N' FOR '
   + QUOTENAME(@SynonymForServerName)
   + N'.'
   + QUOTENAME(@SynonymForDatabaseName)
   + N'.'
   + QUOTENAME(@SynonymForSchemaName)
   + N'.'
   + QUOTENAME(@SynonymForObjectName)
   + N';'
EXEC sp_executesql @CreateSynonymStatement;
GO

--create certificate and sign proc
CREATE CERTIFICATE CreateSynonymCert
  ENCRYPTION BY PASSWORD = 'T3mP0@rypAsso0rd'
  WITH SUBJECT = 'For CREATE SYNONYM in dbo schema';
ADD SIGNATURE TO dbo.CreateSynonym BY CERTIFICATE CreateSynonymCert WITH PASSWORD = 'T3mP0@rypAsso0rd';

--private key is ephemoral for this purpose so we remove it
ALTER CERTIFICATE CreateSynonymCert REMOVE PRIVATE KEY;

--create a user from certificate with the needed permissions
CREATE USER CreateSynonymCertUser FROM CERTIFICATE CreateSynonymCert;
GRANT CREATE SYNONYM TO CreateSynonymCertUser;
GRANT ALTER ON SCHEMA::dbo TO CreateSynonymCertUser;

--We could grant execute directly to the user but a role is easier to manage
--when multiple users are involved and adheres to RBAC security principles.
CREATE ROLE CreateSynonymRole;
ALTER ROLE CreateSynonymRole ADD MEMBER YourUser;
GRANT EXECUTE ON dbo.CreateSynonym TO CreateSynonymRole;
GO

--example usage
EXECUTE AS USER = 'YourUser';
GO
EXEC dbo.CreateSynonym
     @SynonymSchemaName = N'dbo'
   , @SynonymName = N'MYSYN'
   , @SynonymForServerName  = N'SERVER01'
   , @SynonymForDatabaseName  = N'DEMODB'
   , @SynonymForSchemaName  = N'dbo'
   , @SynonymForObjectName  = N'CHILD';
GO
REVERT;
GO

引用自:https://dba.stackexchange.com/questions/245016