Đ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, để SELECT
truy 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ể SELECT
từ 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:
- tạo chứng chỉ trong cơ sở dữ liệu
- Ký TVF với Giấy chứng nhận
- Sao chép Chứng chỉ (không có Khóa riêng) vào Cơ sở dữ liệu B
- Tạo người dùng trong DatabaseB từ Chứng chỉ
- Cấp
SELECT
quyề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 SELECT
quyề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/