web-dev-qa-db-ja.com

クロスデータベースビュー-現在のセキュリティコンテキストではデータベースにアクセスできません

AdbBdbの2つのデータベースがあります。 Bdbでは、次のようにAdbの別のビューを参照するビューを作成します。CREATE VIEW Bdb.dbo.Bview AS SELECT * FROM Adb.dbo.Aview

SQL認証済みBloginがあり、BuserAdbの両方でBdbにマップされています。少なくともdb_datareader両方の役割。

以下は機能しません:

USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Bdb.dbo.Bview;
SELECT * FROM Adb.dbo.Aview;

両方の選択に対して次のエラーがスローされます。

Msg 916, Level 14, State 1, Line 4
The server principal "Buser" is not able to access the database "Adb" under the current security context.

ただし、これは機能します:

USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Adb.dbo.Aview;
SELECT * FROM Bdb.dbo.Bview;

私が初めてUSE BdbBuserに切り替えます。他のデータベースが表示されません。

USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- only master, tempdb and Bdb is shown

しかし、私がUSE Adb最初に、Buserがなく、アクセスできないものも含め、すべてが表示されます。

USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- all DBs on the server are shown

この問題の原因は何ですか?何をチェックすればよいですか?

3
ROAL

まず最初に:信頼を有効にしないでください!!このような大きなセキュリティホールを開ける理由はまったくありません。 (注:msdbTRUSTWORTHYを有効にしており、Microsoft提供のDBであるため問題ありません。ユーザーが作成したDBは決して必要ではありませんTRUSTWORTHY enabled)

これで、ログインではなくユーザーを偽装するときにこれが機能する場合、[Adb]データベースがTRUSTWORTHY ONとして既に有効になっているため、データベースレベルの偽装を使用するときに存在するデフォルトの隔離が削除されます。次のコマンドを実行すると、これを確認できます。

SELECT db.is_trustworthy_on, *
FROM   sys.databases db
WHERE  db.[name] IN (N'Adb', N'Bdb');

AdbTRUSTWORTHYに対して有効になっていて、Bdbが有効になっていない場合は、TRUSTWORTHYに対してBdbを有効にしないでください。 _。 disableTRUSTWORTHY for Adbを無効にし、モジュール署名を使用してこれを行うのが最善です。

ALTER DATABASE [Adb] SET TRUSTWORTHY OFF;

モジュール署名を介してこのクロスデータベースアクセスを行う例については、私の次の回答(ここではDBA.SE)を参照してください。

別のデータベースのアカウントなしで別のデータベースのテーブルに基づいてビューにアクセス

TRUSTWORTHYではなくモジュール署名(またはデータベース間の所有権の連鎖)を使用する理由の詳細については、次の投稿を参照してください。

偽装、信頼、クロスDB所有権の連鎖の使用を停止してください

一般的なモジュール署名の詳細については、以下を参照してください。

https://ModuleSigning.info/


@Nicが質問のコメントで述べたように、テスト時にはEXECUTE AS LOGINではなくEXECUTE AS USERを使用するのが最善です。ログインはサーバーレベルで行われ、そのログイン用にユーザーが作成されたデータベースにアクセスできます。これは、そのアカウントとしてSQL Serverにログインするのと同じです。

違いの理由は、Microsoftのドキュメントページで EXECUTE ASを使用したデータベース偽装の拡張 に記載されています。

偽装スコープについて

...

ただし、EXECUTE AS USERステートメントを使用してプリンシパルを偽装する場合、またはEXECUTE AS句を使用してデータベーススコープのモジュール内で使用する場合、偽装のスコープはデフォルトでデータベースに制限されます。つまり、データベースのスコープ外のオブジェクトを参照すると、エラーが返されます。

また、「EXECUTE ASを使用したデータベース偽装の拡張」MSDNページ(上記にリンク)には、認証システムとこれらのルールの背後にある理由を説明する多くの優れた情報があります。

これら2つのデータベースはベンダー提供(この回答を送信した後に追加された情報)であるため、EXECUTE AS LOGINに切り替えて変更しない変更を行うのがおそらく最善ですデータベースへ(モジュール署名用)。

6
Solomon Rutzky

Bdbは信頼できるデータベースですか?

SELECT name, is_trustworthy_on FROM sys.databases 

EXECUTE ASを別のDBに使用するには、データベース間に信頼関係を設定する必要があります。

ALTER DATABASE Bdb SET TRUSTWORTHY ON;
GO

ただし、これを行うことにはセキュリティ上の懸念がたくさんあります。実際にリスクを理解している場合にのみ、これを行ってください。

詳しくはこちらをご覧ください: https://technet.Microsoft.com/en-us/library/ms188304(v = sql.105).aspxhttps://support.Microsoft .com/en-us/help/2183687/guidelines-for-using-the-trustworthy-database-setting-in-sql-server

0
JasonBluefire