私たちの開発者は、サーバー(SQL Server 2012 Enterprise Edition)上の他のデータベースからの "sp_"命名規則を使用してマスターデータベースに作成されたストアドプロシージャを実行できる必要があるアプリケーションが使用するドメインアカウントを持っています。
これは推奨される方法ではないことを理解していますが、これを行う決定は、私よりも権限のある他の誰かによって行われました。
サーバー上の任意のデータベースから自分でこのようなストアドプロシージャを実行しても問題はありませんが、sysadmin特権も持っているので、このユーザーにはできるだけ少ないアクセス許可を与えることを望んでいます。
これが私が試したものです:
--create procedure for purpose of testing
USE [master]
GO
CREATE PROCEDURE dbo.sp_HelloWorld
AS
PRINT 'Hello World!'
GO
--create login for test user
USE [master]
GO
CREATE LOGIN [DOMAIN\user] FROM WINDOWS
GO
--create user in master database
USE [master]
GO
CREATE USER [DOMAIN\user] FOR LOGIN [DOMAIN\user]
GO
--create user in another database on server
USE MyDB
GO
CREATE USER [DOMAIN\user] FOR LOGIN [DOMAIN\user]
GO
--grant execute permission on stored procedure in master database
USE [master]
GO
GRANT EXECUTE ON dbo.sp_HelloWorld TO [DOMAIN\user]
GO
実行できますEXEC dbo.sp_HelloWorld
サーバー上の任意のデータベースから問題なく自分自身。
以下も実行できます:
USE [master]
GO
EXECUTE AS USER='DOMAIN\user'
EXEC dbo.sp_HelloWorld
REVERT
しかし、ユーザーを偽装しながら、他のデータベースのコンテキスト内からストアドプロシージャを実行しようとしています。
USE MyDB
GO
EXECUTE AS USER='DOMAIN\user'
EXEC dbo.sp_HelloWorld
REVERT
次のエラーが発生します。
メッセージ229、レベル14、状態5、手順sp_HelloWorld、行1 [バッチ開始行15] EXECUTE権限は、オブジェクト 'sp_HelloWorld'、データベース 'master'、スキーマ 'dbo'で拒否されました。
何が欠けていますか?
何が欠けていますか?
_DOMAIN\user
_ loginは、MyDB
コンテキストで対応するserを使用して_dbo.sp_HelloWorld
_を実行できるはずです。
_EXECUTE AS USER
_コマンドは、エラーが返される理由です。
偽装されるコンテキストが現在のデータベース内のユーザーであることを指定します。偽装の範囲は現在のデータベースに制限されています。データベースユーザーへのコンテキストスイッチは、そのユーザーのサーバーレベルのアクセス許可を継承しません。
重要な部分:偽装の範囲は現在のデータベースに制限されています。
そのため、_EXECUTE AS USER
_を使用する場合、master
などの他のデータベースの権限は適用されません。
正しいログイン/ユーザーマッピングが必要な場合は、_EXECUTE AS LOGIN
_を使用する必要があります
偽装される実行コンテキストがログインであることを指定します。偽装の範囲はサーバーレベルです。
_USE MyDB
GO
EXECUTE AS LOGIN ='DOMAIN\user'
EXEC dbo.sp_HelloWorld
REVERT
_
結果
_Hello World!
_