多くの異なるテーブルからの多くの異なる列を含むストアドプロシージャがあります。 Excelを介してストアドプロシージャの結果に20人のユーザーがアクセスできるようにしたい.
ユーザーがストアドプロシージャにのみアクセスでき、基になるテーブルやビューにはアクセスできないようにすることはできますか?
もちろん、これらのユーザーに、基になるテーブルではなく、ストアドプロシージャへの権限を与えるだけです。
CREATE PROCEDURE dbo.test -- always use schema prefix!
AS
BEGIN
SET NOCOUNT ON;
SELECT t1.col1, t2.col2, ...
FROM dbo.table1 AS t1
INNER JOIN dbo.table2 AS t2
ON ... ;
END
GO
GRANT EXEC ON dbo.test TO [user1], [user2], ...;
これは、テストできる完全に含まれた例です。最初に、データベースを作成します(うまくいけば、floob
は既存のデータベースと競合しません)。
CREATE DATABASE floob;
GO
次に、2つのログインを作成します。
CREATE LOGIN floob1 WITH PASSWORD = 'foo', CHECK_POLICY = OFF;
CREATE LOGIN floob2 WITH PASSWORD = 'foo', CHECK_POLICY = OFF;
GO
そして、一緒に行くデータベースユーザーを作成します:
USE floob;
GO
CREATE USER floob1 FROM LOGIN floob1;
CREATE USER floob2 FROM LOGIN floob2;
GO
次に、デフォルトでアクセスできないテーブルと、それをクエリするストアドプロシージャを作成します。
CREATE TABLE dbo.whatwhat(id INT);
INSERT dbo.whatwhat(id) VALUES(1);
GO
CREATE PROCEDURE dbo.select_whatwhat
AS
BEGIN
SET NOCOUNT ON;
SELECT id FROM dbo.whatwhat;
END
GO
次に、floob1
のみに実行権限を付与します。
GRANT EXEC ON dbo.select_whatwhat TO floob1;
GO
次に、プロシージャを実行して、テーブルからfloob1
として選択します。
EXECUTE AS USER = 'floob1';
GO
EXEC dbo.select_whatwhat; -- works
GO
SELECT id FROM dbo.whatwhat; -- fails with error
GO
REVERT;
ストアドプロシージャを実行した結果、クエリは成功しますが、テーブルへのクエリを直接実行しようとすると、明示的にアクセスを許可されていないため、エラーメッセージが表示されます。
メッセージ229、レベル14、状態5
オブジェクト 'whatwhat'、データベース 'floob'、スキーマ 'dbo'に対するSELECT権限が拒否されました。
次に、ストアドプロシージャを実行するための明示的なアクセス権を付与されていないfloob2
として試してください。
EXECUTE AS USER = 'floob2';
GO
EXEC dbo.select_whatwhat; -- fails with error
GO
SELECT id FROM dbo.whatwhat; -- fails with error
GO
REVERT;
今回はSELECT
でも同じエラーが発生しますが、EXEC
でもこのエラーが発生します。
メッセージ229、レベル14、状態5、手順select_whatwhat
オブジェクト「select_whatwhat」、データベース「floob」、スキーマ「dbo」に対するEXECUTE権限が拒否されました。
クリーンアップすることを忘れないでください:
USE master;
GO
DROP DATABASE floob;
DROP LOGIN floob1;
DROP LOGIN floob2;
GO
あなたのコメントについて:
T-SQLコードを使用する代わりに、SQLサーバーでドロップアンドクリックを使用してユーザーを許可することはできますか?
それはそうですが、それは非常に良い考えのようには聞こえません。プロセスは次のとおりです。オブジェクトエクスプローラーでストアドプロシージャを右クリックし、[プロパティ]をクリックし、[アクセス許可]タブに移動して、[検索]をクリックし、ユーザー名を入力して[OK]をクリックし、左側のEXECUTEとGRANTが一致するチェックボックスをオンにします上部、[OK]をクリックします。すべてのストアドプロシージャについて繰り返し、20を掛けます(すべてのユーザー)。ええ、それはスクリプトを書くよりもずっと簡単に聞こえます。 GUIを介してインタラクティブにこれを行うために必要なポイントとクリックの数をだれが知っているかではなく、1つのコピー、貼り付け、実行で、必要なスクリプトを1つのステップで生成するより良い方法を次に示します。
DECLARE @xml NVARCHAR(MAX) = N'';
;WITH users AS
(SELECT name = 'user1' UNION ALL SELECT 'user2' ... UNION ALL SELECT 'user20')
SELECT @xml += N'GRANT EXEC ON ' + QUOTENAME(s.name) +
'.' + QUOTENAME(p.name) + ' TO ' + QUOTENAME(u.name) + ';
'
FROM users AS u CROSS JOIN sys.procedures AS p
INNER JOIN sys.schemas AS s ON s.[schema_id] = p.[schema_id];
PRINT @sql;
-- EXEC sp_executesql @sql;
sys.database_principals
をミックスに追加して、タイプミスのない適切なユーザーセットを確実に取得することもできます。