SQL Server: cấp quyền truy cập chọn cho người dùng trong chế độ xem chứ không phải trong bảng của nó


11

Tôi có một phiên bản SQL Server 2012 với một vài cơ sở dữ liệu. Trong một trong số đó, tôi đã tạo một khung nhìn, chọn các bảng trong nhiều hơn một cơ sở dữ liệu.

Tôi muốn người dùng có thể chọn chế độ xem đó, nhưng không được chọn các bảng của nó. Chế độ xem được tạo chính xác vì người dùng không thể chọn các bảng.

Tôi đã đọc /programming/368414/grant-select-on-a-view-not-base-tablehttp://msdn.microsoft.com/en-us/l Library / ms188676. aspx và nó vẫn không hoạt động.

Nếu tôi làm một GRANT SELECT TABLE TO USER tất cả các bảng, người dùng có thể chọn chế độ xem. Nhưng nếu tôi thu hồi bất kỳ bảng nào, nó sẽ thất bại.

Đây có thể là một thủ tục dễ thực hiện, nhưng tôi gặp khó khăn để làm cho nó hoạt động. Tôi đã thấy nó xảy ra trước đây (chủ sở hữu của một ví dụ đã cho tôi quyền truy cập vào một khung nhìn và không làm điều đó với các bảng của nó) nhưng tôi không thể làm điều đó hoặc tìm ai đó biết cách.

Ai đó có thể cung cấp cho tôi một hướng dẫn về cách làm điều đó, hoặc một ví dụ mã?


Khi người dùng SELECTsxem tôi nhận được thông báo:

Quyền SELECT đã bị từ chối trên đối tượng <TABLE>, cơ sở dữ liệu <DB>, lược đồ dbo.

Nếu tôi cấp chọn cho bảng đó, thông báo lỗi sẽ thay đổi tên bảng sang bảng khác mà khung nhìn sẽ đọc.


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Paul White 9

Câu trả lời:


21

Nếu bạn muốn người dùng chọn từ chế độ xem, tại sao bạn cấp cho bảng? Bằng cách "thu hồi", bạn có nghĩa là thu hồi / từ chối rõ ràng? Từ chối sẽ ghi đè cấp vì vậy có vấn đề của bạn ... bạn sẽ có thể thực hiện việc này bằng cách thêm cấp cho chế độ xem và không làm bất cứ điều gì theo cách trên bảng.

Đây là một ví dụ nhanh, nơi SELECTchưa được cấp rõ ràng trên bàn, nhưng đã được xem. Người dùng có thể chọn từ chế độ xem nhưng không phải bảng.

CREATE USER foo WITHOUT LOGIN;
GO
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT);
GO
CREATE VIEW dbo.v 
AS 
  SELECT a.id FROM a INNER JOIN b ON a.id = b.id;
GO
GRANT SELECT ON dbo.v TO foo;
GO
EXECUTE AS USER = N'foo';
GO
-- works:
SELECT id FROM dbo.v;
GO
-- Msg 229, SELECT denied:
SELECT id FROM dbo.a;
GO
REVERT;

Lưu ý rằng giả định foonày đã không được cấp đặc quyền nâng cao thông qua các quyền rõ ràng trên lược đồ hoặc cơ sở dữ liệu hoặc thông qua vai trò hoặc thành viên nhóm.

Vì bạn đang sử dụng các bảng trong nhiều cơ sở dữ liệu (xin lỗi, tôi đã bỏ lỡ phần cuối của câu đầu tiên đó), nên bạn cũng có thể cần các khoản trợ cấp rõ ràng trên (các) bảng trong cơ sở dữ liệu nơi chế độ xem không tồn tại. Để tránh cấp quyền chọn cho (các) bảng, bạn có thể tạo chế độ xem trong mỗi cơ sở dữ liệu và sau đó tham gia các chế độ xem.

Tạo hai cơ sở dữ liệu và đăng nhập:

CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO

Trong cơ sở dữ liệu d1, tạo người dùng, sau đó tạo bảng và chế độ xem đơn giản đối với bảng đó. Cấp chọn cho người dùng chỉ chống lại chế độ xem:

USE d1;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t1(id INT);
GO
CREATE VIEW dbo.v1
AS
  SELECT id FROM dbo.t1;
GO
GRANT SELECT ON dbo.v1 TO blat;
GO

Bây giờ, trong cơ sở dữ liệu thứ hai, tạo người dùng, sau đó tạo một bảng khác và một khung nhìn nối bảng đó với khung nhìn trong d1. Cấp chỉ chọn để xem.

USE d2;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t2(id INT);
GO
CREATE VIEW dbo.v2
AS
  SELECT v1.id FROM dbo.t2 
    INNER JOIN d1.dbo.v1 AS v1
    ON t2.id = v1.id;
GO
GRANT SELECT ON dbo.v2 TO blat;
GO

Bây giờ hãy khởi chạy một cửa sổ truy vấn mới và thay đổi thông tin đăng nhập để đăng nhập blat( EXECUTE ASkhông hoạt động ở đây). Sau đó chạy phần sau từ ngữ cảnh của một trong hai cơ sở dữ liệu và nó sẽ hoạt động tốt:

SELECT id FROM d1.dbo.v2;

Cả hai sẽ mang lại lỗi 229 Msg:

SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;

Các kết quả:

Msg 229, Cấp 14, Trạng thái 5, Dòng 1
Quyền đã bị từ chối trên đối tượng 't1', cơ sở dữ liệu 'd1', lược đồ 'dbo'.
Msg 229, Cấp 14, Trạng thái 5, Dòng 3
Quyền đã bị từ chối trên đối tượng 't2', cơ sở dữ liệu 'd2', lược đồ 'dbo'.


1

Câu trả lời wiki cộng đồng ban đầu được thêm vào câu hỏi của tác giả:

Đây là những gì tôi đã làm:

  1. Tạo một khung nhìn trong DB A, nối tất cả các bảng trong đó.
  2. Cấp SELECTquyền truy cập cho người dùng trên chế độ xem đó và KHÔNG cho bất kỳ bảng nào của nó. Người dùng đã có thể truy vấn thành công khung nhìn và không phải các bảng.
  3. Tạo chế độ xem trong DB B, nối các bảng trong DB này cùng với chế độ xem trong DB A.
  4. Cấp SELECTquyền truy cập cho người dùng trên chế độ xem thứ hai này và cũng KHÔNG cho bất kỳ bảng nào. Người dùng đã có thể truy vấn thành công chế độ xem cuối cùng này và xem dữ liệu.

Tôi nghĩ thật lạ khi một khung nhìn có thể truy vấn các bảng trong DB của nó mà người dùng không có quyền truy cập trực tiếp nhưng không thể thực hiện nó trong các bảng từ DB khác. Ít nhất là nó đã làm việc.


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.