user1
とuser2
という2人のユーザーがいます。
User1
にはsysadmin権限があり、saを介してデータベースレベルのトリガーを作成しました。
現在、user2
権限とdb-ddladmin
を持つdb_datareader
を介してテーブルを作成しようとしています。
エラーが発生します:
'Msg 297, Level 16, State 1, Procedure TR_CaptureDBChanges, Line 35
The user does not have permission to perform this action.
コード:
CREATE TRIGGER [TR_CaptureDBChanges]
ON DATABASE
FOR CREATE_PROCEDURE, ALTER_PROCEDURE,DROP_PROCEDURE,CREATE_TABLE, ALTER_TABLE,DROP_TABLE,CREATE_TRIGGER,ALTER_TRIGGER,DROP_TRIGGER,CREATE_VIEW,ALTER_VIEW,DROP_VIEW,CREATE_FUNCTION, ALTER_FUNCTION,
DROP_FUNCTION
BEGIN
DECLARE @ed XML
SET @ed = EVENTDATA()
DECLARE @ip VARCHAR(32) = (SELECT client_net_address FROM sys.dm_exec_connections WHERE session_id = @@SPID);
INSERT INTO DBChangesLogs ( EventDate,DBName)VALUES(GetDate(),@ed.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)'))
END
おそらく問題は、testuser
にVIEW SERVER STATE
サーバーレベルの権限がないことです。 sys.dm_exec_connections DMVにアクセスするには、その権限(DDLトリガーを持つデータベースのユーザーではなく、[master]
データベースのログインに割り当てられている)が必要です。したがって、次のいずれかを実行する必要があります。
GRANT
the testuser
ログインVIEW SERVER STATE
サーバーレベルの権限、または
VIEW SERVER STATE
サーバーレベルのアクセス許可が割り当てられた証明書ベースのログインを作成し、ADD SIGNATUREを使用してその証明書でDDLトリガーに署名します。この手順は、フォロワーの回答に記載されています。
SQL Serverエージェントサービスの状態を確認できるように、ユーザーに最低限必要なアクセス許可を提供する必要がありますか?
セキュリティの観点からは、証明書ベースのログインを処理し、トリガーに署名するために少し余分な作業を行うことをお勧めします。このアプローチでは、実際のログイン/ユーザーに追加の権限は付与されず、DDLトリガーを起動させるアクションを実行するための適切なDDL権限を持つすべてのユーザーに適用されます。また、testuser
は単なるテストケースであり、これらの権限は最終的なシステムでより広く適用する必要があると想定すると、これらすべてのユーザーにVIEW SERVER STATE
を付与したくない場合があります。役割にも。
これらと同じように、所有権チェーンはINSERT
に対するDBChangesLogs
権限を処理するため、ユーザーに明示的に権限を付与する必要がないと考えました。そうでない場合は、このアクセス許可を1人以上のユーザーに付与するのではなく、またはアクセス権を付与するユーザーをdb_datawriter
ロールに追加するよりも確かに優れています(そしてINSERT
だけではありません)すべてのテーブルに対して-このトリガーにDBChangesLogs
テーブルに挿入する機能を許可するには、他の回答ですでに概説されているものを超えて、2つの追加の簡単な手順を実行するだけです。
GRANT
このユーザーINSERT
テーブルに対するDBChangesLogs
権限CREATE USER [MrDoStuff] FROM LOGIN [MrDoStuff];
GRANT INSERT ON dbo.DBChangesLogs TO [MrDoStuff];
PS:@ip
変数を宣言して設定します。この許可の問題が解決したら、あなたはそれを使用すると思いますか?
SELECTステートメントはsys.dm_exec_connections
上にあり、VIEW SERVER STATE
権限が必要です。
したがって、権限を付与するには、次のコマンドを実行します。
USE MASTER
GO
GRANT VIEW SERVER STATE TO user2;
GO
次は、トリガーのINSERT
ステートメントです。ログインuser2
には、DATABASE
テーブルに書き込むテーブルを作成しているDBChangesLogs
に対するdb_datawriter
権限が必要です。
sp_addrolemember
を使用して、読み取りと書き込みを許可できます。
USE [DATABASE_NAME]
GO
EXEC sp_addrolemember N'db_datareader', N'user2'
GO
USE [DATABASE_NAME]
GO
EXEC sp_addrolemember N'db_datawriter', N'user2'
GO
最後に、トリガーの作成に使用しているコードには、BEGINの前に「AS」がありません。