Hạn chế cập nhật trên các cột nhất định. Chỉ cho phép thủ tục được lưu trữ để cập nhật các cột đó


17

Tôi có các cột giá nhạy cảm mà tôi muốn chỉ cập nhật thông qua thủ tục được lưu trữ. Tôi muốn tất cả các nỗ lực mã hoặc thủ công để thay đổi giá trị trong các cột giá này sẽ thất bại nếu nó không sử dụng các thủ tục được lưu trữ được thiết kế để cập nhật nó.

Tôi đang xem xét thực hiện điều này bằng cách sử dụng kích hoạt và bảng mã thông báo. Ý tưởng tôi đang xem xét là có một bảng mã thông báo. các thủ tục được lưu trữ sẽ phải chèn giá trị đầu tiên vào bảng mã thông báo. Sau đó cập nhật các cột giá. Trình kích hoạt cập nhật sẽ kiểm tra xem mã thông báo có tồn tại trong bảng mã thông báo cho hàng được cập nhật hay không. Nếu tìm thấy, nó sẽ tiếp tục. nếu không tìm thấy mã thông báo, nó sẽ ném ngoại lệ và khiến giao dịch cập nhật không thành công.

Có cách nào tốt / tốt hơn để thực hiện hạn chế này không?


1
Bạn có thể sử dụng chế độ xem để bảo mật dựa trên cột. Điều đó sẽ thanh lịch hơn nhiều so với một kích hoạt. Cung cấp cho người dùng quyền trên xem nhưng không phải dữ liệu cơ bản.
Thomas Stringer

Đó là một điểm tốt. Nhưng vấn đề vẫn chưa được giải quyết mà không phá vỡ nhiều ứng dụng đang sử dụng kết nối tổng hợp.
Elias

Bạn có thể giải thích làm thế nào điều này sẽ "phá vỡ rất nhiều ứng dụng đang sử dụng kết nối tổng hợp" không?
Aaron Bertrand

Câu trả lời:


21

SQL Server cho phép cấp quyền cột. Ví dụ:

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

Cảm ơn Michal, nhưng giải pháp này sẽ không hiệu quả với tôi bởi vì, ứng dụng của tôi là một ứng dụng web đang sử dụng kết nối tổng hợp. Tất cả người dùng kết nối bằng cùng một Chuỗi kết nối máy chủ SQL.
Elias

1
@Elias Tôi không hiểu. Chuỗi kết nối kết nối như một người dùng cụ thể, phải không? Vì vậy, thay thế SampleRolebằng người dùng đó ...
Aaron Bertrand

quyền cấp cột là cách để đi đến đây. Điều đó và đảm bảo rằng các nhà phát triển biết rằng thực hiện thay đổi giá trị thông qua t-sql trực tiếp sẽ phá hủy hệ thống.
mrdenny

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

Nếu tất cả người dùng của bạn có cùng thông tin đăng nhập (ouch, BTW) thì đây là một tùy chọn khác

  • thu hồi quyền cập nhật từ người dùng đó (hoặc vai trò, nếu bạn đang làm theo cách đó).
  • Thay đổi Proc được lưu trữ với mệnh đề "thực hiện như chủ sở hữu" trên đó
  • sau đó, Proc được lưu trữ sẽ chạy với quyền của người dùng sở hữu lược đồ chứa nó (nếu nó nằm trong dbođó thì bạn đã được bảo vệ).

Người dùng ứng dụng thông thường sẽ thiếu quyền cập nhật cho bảng đó, vì vậy họ sẽ không thể cập nhật nó theo bất kỳ cách nào khác.


Bạn không cần tạo một người dùng mới để làm điều này ...
Aaron Bertrand

@aaronbertrand bạn đúng - vì vậy, e reasonni đã nghĩ rằng bạn sẽ "thực thi như người tạo", nhưng đó không phải là điều - bạn có thể "thực thi với tư cách là chủ sở hữu" miễn là người dùng sở hữu lược đồ có quyền cập nhật bảng đó. Nếu Proc được lưu trữ trong dbo, thì bạn được bảo hiểm. Tôi sẽ cập nhật câu trả lời của tôi.
SqlRyan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.