web-dev-qa-db-ja.com

ビュー内のすべてのシノニムに権限を付与するにはどうすればよいですか?

ビューに権限を付与する必要があります。 dbo.my_view、ただし、このビューは多くのテーブルと他のビューおよびシノニムを結合します。

次のスクリプトを使用すると、サーバー内のすべての同義語を見つけることができます。

同義語の内容をリストするスクリプト

SELECT
name as synonymName,
base_object_name as synonymDefinition,
COALESCE(PARSENAME(base_object_name,4),@@SERVERNAME) AS serverName,
COALESCE(PARSENAME(base_object_name,3),DB_NAME(DB_ID())) AS dbName,
COALESCE(PARSENAME(base_object_name,2),SCHEMA_NAME(SCHEMA_ID())) AS schemaName,
PARSENAME(base_object_name,1) AS objectName
FROM sys.synonyms
ORDER BY serverName,dbName,schemaName,objectName

dbo.myviewで選択を付与する必要がある場合、類義語も付与する必要があるため、他のデータベースで付与する必要がある選択権限を確認するにはどうすればよいですか?

1

マルチェロはこのようなクエリについて尋ねられたと思います:

select  d.referenced_entity_name,
        s.name as synonymName,
        base_object_name as synonymDefinition,
        COALESCE(PARSENAME(s.base_object_name,4),@@SERVERNAME) AS serverName,
        COALESCE(PARSENAME(s.base_object_name,3),DB_NAME(DB_ID())) AS dbName,
        COALESCE(PARSENAME(s.base_object_name,2),SCHEMA_NAME(SCHEMA_ID())) AS schemaName,
        PARSENAME(s.base_object_name,1) AS objectName
from sys.sql_expression_dependencies d
     join sys.synonyms s
        on d.referenced_id = s.object_id
where d.referencing_id = object_id('dbo.myView'); 

このクエリは、ビューで使用される同義語を単に表示しますdbo.myViewと、Marcelloのクエリを使用したそれらの定義。

証明書は有効なアプローチですが、すべてのビューをUDFに変えることは不可能である可能性があります。また、異なるサーバー間で特定のアプローチを実装できるかどうかはわかりません。つまり、一部の同義語はリンクサーバーを参照できます。

そしてこのクエリは、シノニム定義とともにシノニムを使用するすべてのビューを示しています。

select  distinct
        o.name as view_name,
        --d.referenced_entity_name,
        s.name as synonymName,
        base_object_name as synonymDefinition,
        COALESCE(PARSENAME(s.base_object_name,4),@@SERVERNAME) AS serverName,
        COALESCE(PARSENAME(s.base_object_name,3),DB_NAME(DB_ID())) AS dbName,
        COALESCE(PARSENAME(s.base_object_name,2),SCHEMA_NAME(SCHEMA_ID())) AS schemaName,
        PARSENAME(s.base_object_name,1) AS objectName
from sys.sql_expression_dependencies d
     join sys.objects o
        on o.object_id = d.referencing_id and o.type = 'V'
     join sys.synonyms s
        on d.referenced_id = s.object_id
order by 1;
1
sepupic

データベース間の権限は非常に扱いにくいものです。だから、ここで私の答えに似ています:

SQL Serverエージェントサービスの状態を確認できるように、ユーザーに最低限必要なアクセス許可を提供する必要がありますか?

最終的には他の方法よりも安全で複雑ではないため、これを実現するには module signing を使用することをお勧めします。これには、ビューを複数ステートメントのテーブル値関数に変更する必要があります。これにより、署名を付けて、まだ選択することができます。

次のようにしてください:

  1. このビューを含むDBで、証明書を作成します(私の好みは、保護のためにデータベースマスターキー(DMK)に依存するのではなく、パスワードを指定することです)。
  2. ADD SIGNATUREを使用して、証明書でTVFに署名します
  3. 証明書をファイルにバックアップします(a 。cer公開鍵のファイルa.k.a.「証明書」、および。pvk秘密鍵のファイル)
  4. ALTER CERTIFICATEを使用して証明書の秘密鍵を削除します
  5. USE [master];
  6. 。cerファイルから同じ証明書を作成します(-。pvkから秘密鍵を作成する必要はありません)。
  7. その証明書からログインを作成する
  8. 目標を達成するために必要なすべての権限をログインに付与します(別名「git 'er done」)。これはCONNECT ANY DATABASE(2016年にあると思います)と他の何か、おそらくCONTROL SERVERまでの組み合わせかもしれません。権限の組み合わせが機能しない場合は、代わりにこのログインをsysadmin固定サーバーロールに追加してみてください。

証明書ベースのログインに付与されるアクセス許可は、しかしとかなり多く、ログインは偽装できず(つまり、EXECUTE AS LOGIN = N'that_Login';)、ログインできません。そのログインは、追加のアクセス許可の単なるコンテナーであり、その証明書で署名されたものにのみ適用されます。この場合は、1つのTVFであり、SELECTステートメントです。

そのTVF内のコードを変更する必要がある場合、またはADD SIGNATUREで署名して別のモジュールにそれらの権限を付与する必要がある場合は、署名する新しいコードが別のコードにある場合、別のDBに同じ証明書を作成する必要があります。 DB、またはALTER CERTIFICATEステートメントを使用して、秘密鍵をこの証明書に復元する必要があります。 2つの組み込み関数を使用してVARBINARYの16進バイト文字列に公開鍵と秘密鍵を抽出し、それらのVARBINARY文字列から新しい証明書を作成できます(SQL Server 2012以降)。 。pvkファイルからのみ証明書の秘密鍵を復元します。したがって、上記のステップ3でBACKUP CERTIFICATEを使用するには、他のDBで完全な証明書を作成する場合と、ここで既存の証明書に秘密鍵を復元する場合の両方に使用できます。

1
Solomon Rutzky