Ограничить обновление для определенных столбцов. Разрешить только хранимую процедуру для обновления этих столбцов

17

У меня есть чувствительные ценовые столбцы, которые я хотел бы обновить только через хранимую процедуру. Я хотел бы, чтобы все попытки кода или ручного изменения значений в этих ценовых столбцах потерпели неудачу, если он не использует хранимые процедуры, предназначенные для его обновления.

Я рассматриваю реализацию этого с использованием триггеров и таблицы токенов. Идея, которую я рассматриваю, состоит в том, чтобы иметь таблицу токенов. хранимые процедуры должны будут сначала вставить значения в таблицу токенов. Затем обновите столбцы цен. Триггер обновления проверит, существует ли токен в таблице токенов для обновленной строки. Если будет найдено, это будет продолжаться. если токен не найден, он выдаст исключение и сделает транзакцию обновления неудачной.

Есть ли хороший / лучший способ реализовать это ограничение?

Элиас
источник
1
Вы можете использовать представление для безопасности на основе столбцов. Это будет намного элегантнее, чем курок. Дайте пользователям разрешение на просмотр, но не базовые данные.
Томас Стрингер
Это хороший момент. Но проблема остается нерешенной, не ломая много приложений, которые используют пул соединений.
Элиас
Можете ли вы объяснить, как это «сломает множество приложений, использующих пул соединений»?
Аарон Бертран

Ответы:

21

SQL Server допускает разрешения на уровне столбцов. Просто для примера:

GRANT UPDATE ON dbo.Person (FirstName, LastName) TO SampleRole;
DENY UPDATE ON dbo.Person (Age, Salary) TO SampleRole;

источник
Спасибо, Михал, но это решение не подойдет мне, потому что мое приложение - это веб-приложение, использующее пул соединений. Все пользователи подключаются с использованием одной и той же строки подключения SQL Server.
Элиас
1
@ Элиас, я не понимаю. Строка подключения подключается как определенный пользователь, верно? Поэтому замените SampleRoleэтим пользователем ...
Аарон Бертран
Разрешения на уровне столбцов - вот путь. Это и гарантия того, что разработчики знают, что внесение изменений в значения через t-sql напрямую разрушит систему.
Мрденни
6
-- 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;
Аарон Бертран
источник
2

Если все ваши пользователи имеют одинаковый логин (ой, кстати), здесь есть еще один вариант

  • отозвать права на обновление у этого пользователя (или роли, если вы делаете это таким образом).
  • Измените хранимый процесс с предложением «выполнить как владелец»
  • тогда сохраненный процесс будет работать с правами пользователя, которому принадлежит схема, в которой он находится (если он включен dbo, то вы уже охвачены).

Обычные пользователи приложения не будут иметь прав на обновление этой таблицы, поэтому они не смогут обновить ее любым другим способом.

SqlRyan
источник
Вам не нужно создавать нового пользователя, чтобы сделать это ...
Аарон Бертран
@aaronbertrand Вы правы - потому что, почему бы ни думал, вы бы сделали «исполнить как создатель», но это не так - вы можете выполнить «выполнить как владелец», если пользователь, владеющий схемой, имеет права на обновить эту таблицу. Если сохраненный процесс находится в dbo, то вы защищены. Я обновлю свой ответ.
SqlRyan