web-dev-qa-db-ja.com

特定の列の更新を制限します。ストアドプロシージャのみがこれらの列を更新できるようにする

機密性の高い価格列があり、ストアドプロシージャを介してのみ更新したい。更新するように設計されたストアドプロシージャを使用していない場合、これらの価格列の値を変更するすべてのコードまたは手動の試行が失敗するようにしてください。

トリガーとトークンテーブルを使用してこれを実装することを検討しています。私が検討しているアイデアは、トークンテーブルを持つことです。ストアドプロシージャは、最初にトークンテーブルに値を挿入する必要があります。次に、価格列を更新します。更新トリガーは、更新された行のトークンテーブルにトークンが存在するかどうかをチェックします。見つかった場合は続行されます。トークンが見つからない場合、例外がスローされ、更新トランザクションが失敗します。

この制限を実装する良い/より良い方法はありますか?

17
Elias

SQL Serverでは、列レベルの権限を許可しています。ちょうど例:

GRANT UPDATE ON dbo.Person (FirstName, LastName) TO SampleRole;
DENY UPDATE ON dbo.Person (Age, Salary) TO SampleRole;
22
user6426
-- prevent your web app user from updating that column directly:

DENY UPDATE ON dbo.YourTable(Price) TO WebApplicationUserName;
GO

-- create a stored procedure while logged in as sysadmin:

CREATE PROCEDURE dbo.UpdateYourTable
  @ProductID INT,
  @Price DECIMAL(10,2)
WITH EXECUTE AS OWNER
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE dbo.YourTable 
    SET Price = @Price
    WHERE ProductID = @ProductID;
END
GO

-- grant explicit access only to that stored procedure to the web app user:

GRANT EXEC ON dbo.UpdateYourTable TO WebApplicationUserName;
6
Aaron Bertrand

すべてのユーザーが同じログインを持っている場合(さて、BTW)、ここに別のオプションがあります

  • そのユーザー(またはその方法で実行している場合はロール)から更新権限を取り消します。
  • "所有者として実行"句を使用してストアドプロシージャを変更する
  • その後、ストアドプロシージャは、それが存在するスキーマを所有するユーザーの権限で実行されます(dboにある場合は、既にカバーされています)。

通常のアプリケーションユーザーはそのテーブルに対する更新権限を持たないため、他の方法では更新できません。

2
SqlRyan