यह मॉड्यूल साइनिंग का उपयोग करके बहुत सुरक्षित तरीके से पूरा करना आसान है। यह मेरे निम्नलिखित दो उत्तरों के समान होगा, यहाँ DBA.StackExchange पर भी, जो कि सिर्फ करने के उदाहरण देते हैं:
निष्पादित प्रक्रिया के साथ संग्रहीत कार्यविधि सुरक्षा, क्रॉस डेटाबेस क्वेरीज़, और मॉड्यूल साइनिंग
क्रॉस डेटाबेस प्रमाणपत्र का उपयोग करते समय ट्रिगर में अनुमतियाँ
इस विशेष प्रश्न के लिए अंतर यह है कि यह एक दृश्य से संबंधित है, और दृश्य पर हस्ताक्षर नहीं किए जा सकते हैं। इसलिए, आपको व्यू को एक मल्टी-स्टेटमेंट टेबल-वैल्यूड फंक्शन (TVF) में बदलना होगा, क्योंकि उन पर हस्ताक्षर किए जा सकते हैं और उन्हें व्यू की तरह एक्सेस किया जा सकता है (अच्छी तरह से SELECT
एक्सेस के लिए)।
निम्नलिखित उदाहरण कोड यह दर्शाता है कि लॉगिन / उपयोगकर्ता "प्रतिबंधित" में केवल इस सवाल का अनुरोध किया जा रहा है कि केवल "डेटाबेसए" तक पहुंच है और अभी भी "डेटाबेसबी" से डेटा प्राप्त करने में सक्षम है। यह केवल इस एक TVF से चुनकर काम करता है , और केवल इस पर हस्ताक्षर होने के कारण।
इस प्रकार के क्रॉस-डेटाबेस एक्सेस को एक दृश्य का उपयोग करते समय पूरा करना, और उपयोगकर्ता को कोई अतिरिक्त अनुमति नहीं देना, क्रॉस-डेटाबेस स्वामित्व चैनिंग को सक्षम करने की आवश्यकता होगी। यह बहुत कम सुरक्षित है क्योंकि यह दोनों डेटाबेस के बीच सभी वस्तुओं के लिए पूरी तरह से खुला है (यह कुछ वस्तुओं और / या उपयोगकर्ताओं के लिए प्रतिबंधित नहीं किया जा सकता है)। मॉड्यूल साइनिंग बस इस एक टीवीएफ को क्रॉस-डीबी एक्सेस की अनुमति देता है (उपयोगकर्ता के पास अनुमति नहीं है, टीवीएफ करता है), और जो उपयोगकर्ता SELECT
टीवीएफ से नहीं कर सकते हैं उनके पास "डेटाबेसबी" तक कोई पहुंच नहीं है।
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;
उपरोक्त सभी चरण वर्तमान स्थिति को फिर से बनाते हैं: उपयोगकर्ता के पास डेटाबेसए तक पहुंच होती है, उसे डेटाबेसए में किसी वस्तु के साथ बातचीत करने की अनुमति होती है, लेकिन डेटाबेसबी में उस वस्तु के कारण डेटाबेसबी में कुछ वस्तु तक पहुंचने में त्रुटि होती है, जहां उपयोगकर्ता के पास कोई पहुंच नहीं है।
नीचे दिए गए कदमों ने मॉड्यूल गायन की स्थापना की। यह निम्न कार्य करता है:
- डेटाबेसए में एक प्रमाण पत्र बनाता है
- प्रमाणपत्र के साथ TVF पर हस्ताक्षर करता है
- सर्टिफिकेट (निजी कुंजी के बिना) डेटाबेस बी के लिए
- प्रमाण पत्र से डेटाबेस में एक उपयोगकर्ता बनाता है
- अनुदान
SELECT
प्रमाणपत्र-आधारित उपयोगकर्ता को DatabaseB में टेबल की अनुमति
मॉड्यूल हस्ताक्षर सेटअप:
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;
यदि किसी कारण से, यह देखने के लिए आवश्यक है, तो आप बस ऊपर दिखाए गए टीवीएफ से एक दृश्य बना सकते हैं। और, उस स्थिति में, TVF को केवल व्यू के अनुसार SELECT
एक्सेस करने की आवश्यकता नहीं है, जैसा कि नीचे दिखाया गया है:
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];
और अब इसका परीक्षण करने के लिए:
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;
मॉड्यूल हस्ताक्षर पर अधिक जानकारी के लिए, कृपया देखें: https://ModuleSigning.Info/