web-dev-qa-db-ja.com

ストアドプロシージャとアクセス許可-EXECUTEで十分ですか?

基になるテーブルへのすべてのアクセスがストアドプロシージャを介して行われるSQL Server 2008データベースがあります。一部のストアドプロシージャは、テーブルからレコードを単純に選択しますが、その他のUPDATE、INSERT、およびDELETEです。

ストアドプロシージャがテーブルを更新する場合、ストアドプロシージャを実行するユーザーは、影響を受けるテーブルに対するUPDATE権限も必要ですか、それともストアドプロシージャに対するEXECUTE権限を持っているという事実ですか?

基本的に、ストアドプロシージャに対するEXECUTE権限をユーザーに与えるだけで十分なのか、ストアドプロシージャが機能するためにテーブルにSELECT、UPDATE、DELETE、およびINSERT権限を与える必要があるのか​​疑問に思っています。ありがとうございました。

[EDIT]ほとんどのストアドプロシージャでは、EXECUTEで十分であるように見えます。ただし、「sp_Executesqlを実行」が使用されているストアドプロシージャでは、EXECUTEで十分ではないことがわかりました。関係するテーブルには、「sp_Executesql」内で実行されるアクションに対する権限が必要でした。

34
webworm

ストアドプロシージャの実行権限で十分です。

CREATE TABLE dbo.Temp(n int)

GO
DENY INSERT ON dbo.Temp TO <your role>
GO
CREATE PROCEDURE dbo.SPTemp(@Int int)
AS

INSERT dbo.Temp
SELECT  @Int 

GO

GRANT EXEC ON dbo.SPTemp TO <your role>

GO

その後、(非db_owner)ユーザーには次の権限が付与されます。

EXEC dbo.SPTemp 10
GO

INSERT dbo.Temp --INSERT permission was denied on the object 'Temp'
SELECT  10

ただし、dbo.Tempに挿入しようとするdbo.SPTemp内に動的SQLがある場合、それは失敗します。この場合、テーブルに対する直接許可を付与する必要があります。

12
Noel Abrahams

テーブルとprocの所有者が同じ場合、テーブルのパーミッションはチェックされません(DENYを含む)。スキーマの所有者が同じである限り、異なるスキーマに存在することもできます。

MSDNの 所有権の連鎖 を参照してください

削除された回答のコメントから編集します。

EXECUTE ASが使用されない限り、コンテキストは常に現在のログインです。参照されるオブジェクトのDML権限のみがチェックされません。 referencetableに権限が割り当てられていないストアドプロシージャでOBJECT_ID(referencedtable)を試してください。 NULLを返します。ストアドプロシージャの所有者によって実行された場合、owenerにはreferencetableに対する権限があるため、値が与えられます。

24
gbn

たぶんあなたは使うことができます

「所有者として実行」

以下のようなストアドプロシージャを作成する場合:

create procedure XXX
with execute as owner
as
begin
...
end
go

次に、ストアドプロシージャEXECUTEXXXパーミッションをユーザーに付与するだけです。

4
yuan liu

挿入、更新、または削除を行うストアドプロシージャの実行権限で十分です。テーブルレベルでこれらの権限を付与する必要はありません。実際、私はそのアプローチを思いとどまらせるでしょう。ストアドプロシージャを使用すると、変更の発生をより詳細に制御できます。たとえば、更新を許可する前にいくつかのチェックを行うことができます。ストアドプロシージャを使用すると、誰かがWHERE句を忘れたためにテーブル内のすべての行を削除するなど、重大な事故を防ぐことができます。

2
Bryan Cooper

ありがとうSOかなり!私は同様の問題を抱えていた。これは私を答えに導いた。

IFステートメントにネストされている他のストアドプロシージャを呼び出すストアドプロシージャのテーブルを切り捨てようとしました。

私のエラーは

サーバープリンシパル "domain\my_id"は、現在のセキュリティコンテキストでデータベース "2nd_DB"にアクセスできません。

呼び出し元のストアドプロシージャに切り捨てを行う権限を与えていました(EXECUTE AS SELF)。これは、SELFが2番目のDB。私たちの解決策は、EXECUTE AS SELFを含め、切り捨てを別のSPに移動することでした。次に、truncate SPを呼び出し、データ処理を実行し、ロジックを決定して、適切な3番目のSPを呼び出します。

1
ARLibertarian