Làm cách nào để thêm người dùng có quyền truy cập vào một chế độ xem?


14

Tôi đang làm việc với MSSQL Server Management Studio 2008 và tôi cần đưa ra quan điểm cho bên thứ ba để đối chiếu dữ liệu của họ. Tôi đã tạo chế độ xem phù hợp nhưng tôi gặp sự cố khi tạo người dùng và cấp cho người dùng quyền đó để chọn từ chế độ xem.

Tôi đã theo dõi các trình hướng dẫn để tạo thông tin đăng nhập và người dùng và sau đó thêm chế độ xem của tôi trong phần Bảo mật với hộp cấp quyền được chọn để chọn. Mọi thứ có vẻ ổn nhưng khi tôi đăng nhập với tư cách là người dùng đó và cố gắng thực hiện "Chọn * từ MyViewName", nó đã cho tôi biết rằng quyền chọn đã bị từ chối.

Tôi vừa tạo lại người dùng (lần này chỉ sử dụng SQL thay vì trình hướng dẫn) và được cấp một cách rõ ràng các quyền chọn và bây giờ nó đang báo lỗi cho tôi: Msg 916, Level 14, State 1, Line 2 The server principal "username" is not able to access the database "unrelated_db" under the current security context.(Tôi không biết tại sao nó cố truy cập vào cơ sở dữ liệu không liên quan ...)

Tôi thực sự không biết phải đi đâu từ đây. Một lần nữa, về cơ bản, tất cả những gì tôi cần là tạo một người dùng mà tôi có thể cung cấp cho bên thứ ba để họ kết nối với cơ sở dữ liệu của chúng tôi và chọn từ chế độ xem này.


3
Có xem bảng cơ sở tham chiếu trong cơ sở dữ liệu khác? Nếu vậy, bạn sẽ phải đối phó với chuỗi sở hữu. Ngoài ra, hãy chắc chắn rằng bạn hiện có bối cảnh cơ sở dữ liệu được đặt thành cơ sở dữ liệu mong muốn.
Thomas Stringer

Có một số cách để xem các phụ thuộc cho một cái nhìn? Ý tôi là, theo như tôi biết, mọi thứ từ khung nhìn nên được chứa trong cơ sở dữ liệu chính. Chế độ xem chỉ là ba trường, hai trường đến từ bảng chi tiết thanh toán và một trường đến từ liên kết đến bảng chi tiết tài khoản nhưng cả hai bảng đều nằm trong cùng một cơ sở dữ liệu (và cùng cơ sở dữ liệu với chế độ xem).
velojason

Câu trả lời:


16

Vui lòng không sử dụng UI cho việc này. Đó là một mớ hỗn độn khó hiểu.

Tôi nghe có vẻ như những gì bạn muốn là tạo một người dùng trong cơ sở dữ liệu, để đăng nhập cụ thể, người chỉ có quyền chọn từ một chế độ xem. Vì vậy, vì bạn đã có thông tin đăng nhập được tạo:

USE your_db;
GO
CREATE USER username FROM LOGIN username;
GO
GRANT SELECT ON dbo.MyViewName TO username;
GO

EDIT ở đây là một ví dụ về một kịch bản sẽ dẫn đến lỗi bạn đề cập.

Đầu tiên, tạo một số bảng trong unrelated_db:

CREATE DATABASE unrelated_db;
GO
USE unrelated_db;
GO
CREATE TABLE dbo.foo(bar INT);
GO

Bây giờ tạo một đăng nhập tương đối hạn chế:

USE [master];
GO
CREATE LOGIN username WITH PASSWORD='foo', CHECK_POLICY = OFF;
GO

Bây giờ hãy tạo cơ sở dữ liệu nơi chế độ xem sẽ tồn tại và thêm thông tin đăng nhập với tư cách người dùng:

CREATE DATABASE velojason;
GO
USE velojason;
GO
CREATE USER username FROM LOGIN username;
GO

Bây giờ hãy tạo một hàm sẽ tham chiếu bảng trong cơ sở dữ liệu khác và đồng nghĩa với bảng khác:

CREATE FUNCTION dbo.checkbar()
RETURNS INT
AS 
BEGIN
    RETURN 
    (
      SELECT TOP (1) bar 
        FROM unrelated_db.dbo.foo 
        ORDER BY bar
    );
END
GO
CREATE SYNONYM dbo.foo FOR unrelated_db.dbo.foo;
GO

Bây giờ tạo một bảng cục bộ:

CREATE TABLE dbo.PaymentDetails
(
  PaymentID INT
);
GO

Bây giờ hãy tạo một khung nhìn tham chiếu bảng, hàm và từ đồng nghĩa và cấp SELECTcho username:

CREATE VIEW dbo.SomeView
AS
  SELECT 
    p.PaymentID, 
    x = dbo.checkbar(), -- function that pulls from other DB
    y = (SELECT bar FROM dbo.foo) -- synonym to other DB
    FROM dbo.PaymentDetails AS p;
GO
GRANT SELECT ON dbo.SomeView TO username;
GO

Bây giờ hãy thử thực hiện dưới dạng usernamevà chỉ chọn cột cục bộ từ chế độ xem:

EXECUTE AS USER = 'username';
GO
  -- even though I don't reference any of the columns 
  -- in the other DB, I am denied SELECT on the view:
SELECT PaymentID FROM dbo.SomeView;
GO
REVERT;
GO

Kết quả:

Msg 916, Cấp 14, Trạng thái 1, Dòng 3
"tên người dùng" chính của máy chủ không thể truy cập cơ sở dữ liệu "unrelated_db" trong bối cảnh bảo mật hiện tại.

Bây giờ thay đổi khung nhìn để không tham chiếu bất kỳ đối tượng bên ngoài nào và chạy lại ở trên SELECTvà nó hoạt động:

ALTER VIEW dbo.SomeView
AS
  SELECT 
    p.PaymentID 
    --x = dbo.checkbar(),
    --y = (SELECT bar FROM dbo.foo)
    FROM dbo.PaymentDetails AS p;
GO

Không hiển thị cho chúng tôi các tập lệnh cho các đối tượng Chi tiết thanh toán, Chi tiết tài khoản và MyView, có thể bạn có thể cho chúng tôi biết nếu truy vấn này trả về bất kỳ kết quả nào. Bạn có thể tìm thấy các tham chiếu đến các đối tượng khác nhau thông qua chế độ xem danh mục sys.sql_expression_dependencies, nhưng chế độ xem này không hoàn hảo - tôi tin rằng nó phụ thuộc vào tất cả các chế độ xem được làm mới (ví dụ trong trường hợp các khung nhìn tham chiếu các khung nhìn khác, hoặc lược đồ cơ bản đã thay đổi) theo thứ tự là chính xác.

DECLARE 
  @dbname   SYSNAME = N'unrelated_db',
  @viewname SYSNAME = N'dbo.SomeView';

SELECT DISTINCT 
    [This object] = 
    OBJECT_SCHEMA_NAME([referencing_id]) 
      + '.' + OBJECT_NAME([referencing_id]), 
    [references this object] = 
    OBJECT_SCHEMA_NAME([referenced_id]) 
      + '.' + OBJECT_NAME([referenced_id]), 
    [and touches this database] = referenced_database_name,
    [and is a(n)] = o.type_desc,
    [if synonym, it references] = s.base_object_name
FROM sys.sql_expression_dependencies AS d
LEFT OUTER JOIN sys.objects AS o
ON o.[object_id] = d.referenced_id
LEFT OUTER JOIN sys.synonyms AS s
ON d.referenced_id = s.[object_id]
AND s.base_object_name LIKE '%[' + @dbname + ']%'
WHERE OBJECT_ID(@viewname) IN (
        referenced_id, 
        referencing_id, 
        (SELECT referencing_id FROM sys.sql_expression_dependencies 
        WHERE referenced_database_name = @dbname)
) OR referenced_database_name = @dbname;

SQL Server sẽ không cố gắng truy cập unrelated_dbđể giải trí cho nó ... phải có một số ràng buộc với cơ sở dữ liệu đó từ chế độ xem bạn đang cố gắng sử dụng. Thật không may nếu chúng ta không thể nhìn thấy định nghĩa chế độ xem và biết thêm chi tiết về các đối tượng mà nó chạm vào, tất cả những gì chúng ta có thể làm là suy đoán. Hai điều chính tôi có thể nghĩ đến là từ đồng nghĩa hoặc hàm sử dụng tên ba phần, nhưng xem các tập lệnh thực tế sẽ cho chúng ta một ý tưởng tốt hơn nhiều thay vì đoán. :-)

Bạn cũng có thể muốn kiểm tra sys.dm_sql_referenced_entities, tuy nhiên hàm này trả về không có gì hữu ích trong ví dụ trên.


6
create login YourTpvLogin with password = 'enter new password here'
go

use SomeDb
go

create user YourTpvUser for login YourTpvLogin
go

grant select on YourView to YourTpvUser
go

Bạn có thể kiểm tra điều này bằng cách làm như sau:

execute as user = 'YourTpvUser'
go

select *
from YourView

revert
go

Rõ ràng điều này không cấp đặc quyền đệ quy. Người dùng được phép chọn từ "YourView" nhưng nếu "YourView" phụ thuộc vào các mối quan hệ / cơ sở dữ liệu khác, thì nó sẽ thất bại: Hiệu trưởng máy chủ "YourTpvUser" không thể truy cập cơ sở dữ liệu "OtherDb" trong bối cảnh bảo mật hiện tại.
lilalinux
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.