Chế độ xem truy cập dựa trên bảng trong cơ sở dữ liệu khác không có tài khoản trong cơ sở dữ liệu khác đó


10

Tôi đã tạo view trong cơ sở dữ liệu1 dựa trên các bảng trong cơ sở dữ liệu2. Tôi đã cấp SELECTquyền cho người dùng chỉ truy cập vào cơ sở dữ liệu1. Người dùng không thể có chế độ xem này để hoạt động vì anh ta không có tài khoản trong cơ sở dữ liệu2. Làm thế nào tôi có thể giải quyết vấn đề này? Tôi không muốn tạo một tài khoản trong cơ sở dữ liệu2.


1
@mustaccio Không, đây không phải là bản sao của câu hỏi / câu trả lời khác vì tình huống đó nằm trong cùng một cơ sở dữ liệu và câu hỏi này là về cơ sở dữ liệu mở rộng. Theo mặc định đó là không được phép. Người ta sẽ phải kích hoạt chuỗi sở hữu cơ sở dữ liệu chéo, và đó là một lỗ hổng bảo mật rất lớn để mở cho một nhu cầu hẹp như vậy.
Solomon Rutzky

1
@SolomonRutzky, tôi sẽ không gọi DB_CHAINING là "lỗ hổng bảo mật khổng lồ". Trong các môi trường sản xuất điển hình nơi chỉ các thành viên vai trò sysadmin có thể tạo đối tượng, đó không phải là vấn đề. Điều đó nói rằng, nó nên được sử dụng cẩn thận trong trường hợp các thành viên vai trò không phải là sysadmin có quyền kiểm soát trên các lược đồ khác với các lược đồ mà họ sở hữu.
Dan Guzman

@DanGuzman "Hãy tin tôi, mọi thứ sẽ luôn đi theo kế hoạch" không phải là một chiến lược hiệu quả. Theo logic đó, hầu như không có rủi ro trong việc thiết lập TRUSTWORTHY ONhoặc đăng nhập ứng dụng như sa. Chuỗi sở hữu DB và TRUSTWORTHYtồn tại chủ yếu do là giải pháp duy nhất tại thời điểm đó. Nhưng bây giờ, ngay cả khi không phải là một rủi ro lớn, DB Chaining chắc chắn là một rủi ro không cần thiết vì Việc ký kết mô-đun không quá khó khăn. Và nếu một người dựa vào chuỗi DB và sau đó sử dụng SQL động, thì nhiều khả năng họ sẽ thiết lập TRUSTWORTHY ONđể sửa nó, trong khi với Mô-đun ký thì nó sẽ không bị hỏng.
Solomon Rutzky 17/12/17

@SolomonRutzky, tôi đã đề nghị ký mô-đun nếu câu hỏi là về một mô-đun thay vì chế độ xem. Suy nghĩ của tôi DB_CHAININGlà không có nhiều rủi ro hơn so với quyền sở hữu trong cơ sở dữ liệu khi các đối tượng nên có trong cùng một cơ sở dữ liệu.
Dan Guzman

@DanGuzman Tại sao lại cho rằng "các đối tượng nên có trong cùng một cơ sở dữ liệu"? OP chỉ chỉ ra điều ngược lại vì họ muốn tách biệt quyền truy cập DB. Việc OP sử dụng Chế độ xem là lý do tại sao tôi đề xuất TVF thay vì Thủ tục được lưu trữ, nhưng điều đó không có nghĩa là tiếp tục sử dụng Chế độ xem là cách hành động tốt nhất. Chúng tôi thường đề xuất sửa đổi cấu trúc và / hoặc cách tiếp cận khi có ý nghĩa, như trường hợp ở đây. Tuy nhiên, tôi đã thêm một khung nhìn bao bọc tùy chọn vào câu trả lời của mình. Và, cho rằng việc "dbo" sở hữu mọi thứ là phổ biến nhất, vâng, DB_CHAININGkhá rủi ro.
Solomon Rutzky 17/12/17

Câu trả lời:


9

Điều này rất dễ thực hiện theo cách rất an toàn khi sử dụng Mô-đun ký. Điều này sẽ tương tự như hai câu trả lời sau đây của tôi, cũng ở đây trên DBA.StackExchange, đưa ra ví dụ về việc làm này:

Bảo mật thủ tục được lưu trữ với thực thi như, truy vấn cơ sở dữ liệu chéo và ký mô-đun

Quyền kích hoạt khi sử dụng chứng chỉ cơ sở dữ liệu chéo

Sự khác biệt cho câu hỏi cụ thể này là nó liên quan đến Chế độ xem và Chế độ xem không thể được ký. Vì vậy, Bạn sẽ cần thay đổi Chế độ xem thành Chức năng Bảng giá trị đa bảng (TVF) vì chúng có thể được ký và có thể được truy cập giống như Chế độ xem (tốt, để SELECTtruy cập).

Mã ví dụ sau đây cho thấy thực hiện chính xác những gì đang được yêu cầu trong câu hỏi trong đó Đăng nhập / Người dùng "RestrictedUser" chỉ có quyền truy cập vào "DatabaseA" và chưa thể lấy dữ liệu từ "DatabaseB". Điều này chỉ hoạt động bằng cách chọn từ một TVF này và chỉ do nó được ký.

Hoàn thành loại quyền truy cập cơ sở dữ liệu chéo này trong khi vẫn sử dụng Chế độ xem và không cung cấp cho Người dùng bất kỳ quyền bổ sung nào, sẽ yêu cầu bật Chuỗi sở hữu cơ sở dữ liệu chéo. Điều đó kém an toàn hơn nhiều vì nó hoàn toàn mở cho tất cả các đối tượng giữa cả hai Cơ sở dữ liệu (không thể giới hạn đối với một số đối tượng và / hoặc Người dùng nhất định). Việc ký mô-đun cho phép chỉ một TVF này có quyền truy cập DB chéo (Người dùng không có quyền, TVF không) và Người dùng không thể SELECTtừ TVF hoàn toàn không có quyền truy cập vào "Cơ sở dữ liệu".

USE [master];

CREATE LOGIN [RestrictedUser] WITH PASSWORD = 'No way? Yes way!';
GO

---

USE [DatabaseA];

CREATE USER [RestrictedUser] FOR LOGIN [RestrictedUser];

GO
CREATE FUNCTION dbo.DataFromOtherDB()
RETURNS @Results TABLE ([SomeValue] INT)
AS
BEGIN
    INSERT INTO @Results ([SomeValue])
        SELECT [SomeValue]
        FROM   DatabaseB.dbo.LotsOfValues;

    RETURN;
END;
GO

GRANT SELECT ON dbo.[DataFromOtherDB] TO [RestrictedUser];
GO
---

USE [DatabaseB];

CREATE TABLE dbo.[LotsOfValues]
(
    [LotsOfValuesID] INT IDENTITY(1, 1) NOT NULL
        CONSTRAINT [PK_LotsOfValues] PRIMARY KEY,
    [SomeValue] INT
);

INSERT INTO dbo.[LotsOfValues] VALUES
    (1), (10), (100), (1000);
GO

---

USE [DatabaseA];

SELECT * FROM dbo.[DataFromOtherDB]();


EXECUTE AS LOGIN = 'RestrictedUser';

SELECT * FROM dbo.[DataFromOtherDB]();
/*
Msg 916, Level 14, State 1, Line XXXXX
The server principal "RestrictedUser" is not able to access
the database "DatabaseB" under the current security context.
*/

REVERT;

Tất cả các bước trên đều tái tạo lại tình huống hiện tại: Người dùng có quyền truy cập vào Cơ sở dữ liệu, có quyền tương tác với một đối tượng trong Cơ sở dữ liệu, nhưng gặp lỗi do đối tượng đó trong Cơ sở dữ liệu truy cập vào Cơ sở dữ liệu mà Người dùng không có quyền truy cập.

Các bước bên dưới thiết lập Mô-đun Hát. Nó làm như sau:

  1. tạo chứng chỉ trong cơ sở dữ liệu
  2. Ký TVF với Giấy chứng nhận
  3. Sao chép Chứng chỉ (không có Khóa riêng) vào Cơ sở dữ liệu B
  4. Tạo người dùng trong DatabaseB từ Chứng chỉ
  5. Cấp SELECTquyền cho Bảng trong DatabaseB cho Người dùng dựa trên Chứng chỉ

Thiết lập ký kết mô-đun:

CREATE CERTIFICATE [AccessOtherDB]
    ENCRYPTION BY PASSWORD = 'SomePassword'
    WITH SUBJECT = 'Used for accessing other DB',
    EXPIRY_DATE = '2099-12-31';

ADD SIGNATURE
    TO dbo.[DataFromOtherDB]
    BY CERTIFICATE [AccessOtherDB]
    WITH PASSWORD = 'SomePassword';

---
DECLARE @CertificatePublicKey NVARCHAR(MAX) =
            CONVERT(NVARCHAR(MAX), CERTENCODED(CERT_ID(N'AccessOtherDB')), 1);

SELECT @CertificatePublicKey AS [Cert / PublicKey]; -- debug

EXEC (N'USE [DatabaseB];
CREATE CERTIFICATE [AccessOtherDB] FROM BINARY = ' + @CertificatePublicKey + N';');
---


EXEC (N'
USE [DatabaseB];
CREATE USER [AccessOtherDbUser] FROM CERTIFICATE [AccessOtherDB];

GRANT SELECT ON dbo.[LotsOfValues] TO [AccessOtherDbUser];
');

---



EXECUTE AS LOGIN = 'RestrictedUser';

SELECT * FROM dbo.[DataFromOtherDB]();
-- Success!!

SELECT * FROM [DatabaseB].[dbo].[LotsOfValues];
/*
Msg 916, Level 14, State 1, Line XXXXX
The server principal "RestrictedUser" is not able to access
the database "DatabaseB" under the current security context.
*/

REVERT;

NẾU TIẾP CẬN CẦN PHẢI QUA MỘT XEM, vì bất kỳ lý do gì, bạn chỉ cần tạo Chế độ xem chọn từ TVF được hiển thị ở trên. Và, trong tình huống đó, không cần phải cấp SELECTquyền truy cập cho TVF, chỉ cho Chế độ xem, như được minh họa dưới đây:

GO
CREATE VIEW dbo.[DataFromTVF]
AS
SELECT [SomeValue]
FROM   dbo.DataFromOtherDB();
GO

-- Remove direct access to the TVF as it is no longer needed:
REVOKE SELECT ON dbo.[DataFromOtherDB] FROM [RestrictedUser];

GRANT SELECT ON dbo.[DataFromTVF] TO [RestrictedUser];

Và bây giờ để kiểm tra nó:

EXECUTE AS LOGIN = 'RestrictedUser';


SELECT * FROM dbo.[DataFromOtherDB]();
/*
Msg 229, Level 14, State 5, Line XXXXX
The SELECT permission was denied on the object 'DataFromOtherDB',
database 'DatabaseA', schema 'dbo'.
*/


SELECT * FROM [OwnershipChaining].[dbo].[LotsOfValues];
/*
Msg 916, Level 14, State 1, Line XXXXX
The server principal "RestrictedUser" is not able to access
the database "DatabaseB" under the current security context.
*/


SELECT * FROM dbo.[DataFromTVF];
-- Success!!


REVERT;

Để biết thêm thông tin về Đăng nhập mô-đun, vui lòng truy cập: https://ModuleSigning.Info/


Các certs được sao lưu như là một phần của bản sao lưu thông thường? Hoặc chúng được lưu trữ ở nơi khác và yêu cầu sao lưu hệ thống tập tin? Và điều gì xảy ra nếu bạn khôi phục lại môi trường thấp hơn có thể sử dụng các mật khẩu khác nhau, v.v.?
Chris Aldrich

@ChrisAldrich Trong cách sử dụng được hiển thị ở đây, nó được sao lưu với DB vì nó hoàn toàn được giữ trong Cơ sở dữ liệu. Nếu bạn sử dụng ALTER CERTIFICATE ... DROP PRIVATE KEYthì khóa riêng sẽ biến mất nếu trước tiên bạn không sao lưu nó vào một tệp bằng BACKUP CHỨNG NHẬN . Nhưng, khóa công khai vẫn còn trong sys.certificates. Và khóa công khai không cần mật khẩu. Chỉ sử dụng khóa riêng để ký một mô-đun yêu cầu mật khẩu (giống nhau trên các máy chủ, không giống như khi bảo vệ thông qua khóa chính).
Solomon Rutzky
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.