SQL Server:ビューではなく、テーブル内のユーザーに選択アクセスを許可します


11

データベースがいくつかあるSQL Server 2012インスタンスがあります。それらの1つで、データベース以外のテーブルを選択するビューを作成しました。

ユーザーがそのビューを選択できるようにしたいのですが、そのテーブルを選択してはなりません。ユーザーがテーブルを選択できないため、ビューが作成されました。

/programming/368414/grant-select-on-a-view-not-base-tableおよびhttp://msdn.microsoft.com/en-us/library/ms188676を読みました。 aspx、それでも動作しません。

GRANT SELECT TABLE TO USERすべてのテーブルに対してaを実行すると、ユーザーはビューを選択できます。しかし、いずれかのテーブルを取り消すと、失敗します。

これは簡単な手順ですが、機能させるのに苦労しています。以前にそれが発生するのを見たことがありますが(インスタンスの所有者がビューへのアクセスを許可し、テーブルへのアクセスを許可しませんでした)、それを実行したり、方法を知っている人を見つけることができません。

誰かがそれを行う方法についてのチュートリアル、またはコード例を私に提供できますか?


ユーザーSELECTsがビューを受け取ると、次のメッセージが表示されます。

オブジェクト<TABLE>、データベース<DB>、スキーマに対するSELECT権限が拒否されましたdbo

そのテーブルに選択を許可すると、エラーメッセージにより、テーブル名がビューが読み取る別のテーブルに変更されます。


コメントは詳細な議論のためのものではありません。この会話はチャットに移動しました
ポールホワイト9

回答:


21

ユーザーがビューから選択できるようにする場合、なぜテーブルに付与するのですか?「取り消す」とは、明示的に取り消す/拒否することを意味しますか?DenyはGrantをオーバーライドするので、問題があります... ビューに Grant 追加し、テーブルに対して何もしないことでこれを実現できるはずです。

以下SELECTは、テーブルで明示的に付与されていないが、ビューで使用されている簡単な例です。ユーザーはビューから選択できますが、テーブルからは選択できません。

CREATE USER foo WITHOUT LOGIN;
GO
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT);
GO
CREATE VIEW dbo.v 
AS 
  SELECT a.id FROM a INNER JOIN b ON a.id = b.id;
GO
GRANT SELECT ON dbo.v TO foo;
GO
EXECUTE AS USER = N'foo';
GO
-- works:
SELECT id FROM dbo.v;
GO
-- Msg 229, SELECT denied:
SELECT id FROM dbo.a;
GO
REVERT;

これはfoo、スキーマまたはデータベースに対する明示的な権限、またはロールまたはグループメンバーシップを介して昇格された権限が付与されていないことを前提としています。

複数のデータベースでテーブルを使用しているため(最初の文の終わりを最初に見逃してしまい申し訳ありません)、ビューが存在しないデータベース内のテーブルに対する明示的な付与も必要になる場合があります。テーブルへの選択の許可を回避するために、各データベースでビューを作成してから、ビューを結合することができます。

2つのデータベースと1つのログインを作成します。

CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO

データベースd1で、ユーザーを作成してから、テーブルとそのテーブルに対する単純なビューを作成します。ビューに対してのみユーザーに選択を許可します。

USE d1;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t1(id INT);
GO
CREATE VIEW dbo.v1
AS
  SELECT id FROM dbo.t1;
GO
GRANT SELECT ON dbo.v1 TO blat;
GO

次に、2番目のデータベースでユーザーを作成してから、別のテーブルと、そのテーブルをのビューに結合するビューを作成しd1ます。ビューにのみ選択を許可します。

USE d2;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t2(id INT);
GO
CREATE VIEW dbo.v2
AS
  SELECT v1.id FROM dbo.t2 
    INNER JOIN d1.dbo.v1 AS v1
    ON t2.id = v1.id;
GO
GRANT SELECT ON dbo.v2 TO blat;
GO

ここで、新しいクエリウィンドウを起動し、ログイン用の資格情報を変更しますblatEXECUTE ASここでは機能しません)。次に、いずれかのデータベースのコンテキストから次のコマンドを実行すると、正常に機能するはずです。

SELECT id FROM d1.dbo.v2;

これらはどちらもMsg 229エラーを生成するはずです。

SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;

結果:

メッセージ229、レベル14、状態5、行1
オブジェクト 't1'、データベース 'd1'、スキーマ 'dbo'に対するSELECT権限が拒否されました。
メッセージ229、レベル14、状態5、行3
SELECT権限がオブジェクト 't2'、データベース 'd2'、スキーマ 'dbo'で拒否されました。


1

最初に作成者によって質問に追加されたコミュニティWikiの回答

これは私がやったことです:

  1. DB Aにビューを作成し、その中のすべてのテーブルを結合しました。
  2. SELECTそのビューでのユーザーへのアクセスが許可され、そのテーブルへのアクセスは許可されません。ユーザーは、テーブルではなくビューを正常にクエリできました。
  3. DB Bにビューを作成し、このDBのテーブルをDB Aのビューと結合しました。
  4. SELECTこの2番目のビューのユーザーにアクセス権を付与しました。また、どのテーブルにもアクセス権を付与していません。ユーザーはこの最終ビューを正常にクエリしてデータを表示することができました。

ビューがそのDB内のテーブルにクエリを実行できるのは奇妙だと思います。ユーザーは直接アクセスできませんが、他のDBからのテーブルでは実行できません。少なくともそれはうまくいった。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.