25

विभिन्न स्कीमा संबंधित प्रश्नों मैंने देखा है से प्रेरित होकर ...एसक्यूएल सर्वर: स्कीमा की अनुमति कैसे दें?

Ownership chaining मुझे टेबल मैं उपयोग पर स्पष्ट अनुमतियों के बिना एक संग्रहीत प्रक्रिया पर निष्पादित, अगर दोनों संग्रहीत प्रक्रिया और टेबल एक ही स्कीमा में हैं प्रदान करने के लिए अनुमति देता है।

यदि हम अलग-अलग स्कीमा का उपयोग करते हैं तो मुझे अलग-अलग-स्कीमा तालिकाओं पर XXX को स्पष्ट रूप से अनुदान देना होगा। स्वामित्व श्रृंखला का उदाहरण दिखाता है कि। इसका मतलब है कि संग्रहीत प्रो निष्पादन उपयोगकर्ता सीधे आपकी टेबल को पढ़/लिख सकता है।

यह कक्षा में आपके इंस्टेंस चर के लिए सीधे पहुंच, गेटटर/सेटर्स को छोड़कर, ब्रेकिंग इंकैप्यूलेशन की तरह होगा।

हम जो भी देखते हैं उसे प्रतिबंधित करने के लिए हम पंक्ति स्तर की सुरक्षा का भी उपयोग करते हैं और हम इसे संग्रहीत प्रक्रियाओं में लागू करते हैं।

तो, हम स्कीमा अलगाव को कैसे बनाए रख सकते हैं और सीधे तालिका पहुंच को कैसे रोक सकते हैं?

बेशक, यदि आप ओआरएम का उपयोग करते हैं या संग्रहीत प्रोसेस का उपयोग नहीं करते हैं तो सवाल लागू नहीं होगा। लेकिन मैं अगर मैं एक ORM या संग्रहीत proc मामले में किसी को भी मुझे स्पष्ट करने की जरूरत महसूस करता है का उपयोग करना चाहिए नहीं पूछ हूँ ...

संपादित करें, उदाहरण के

CREATE USER OwnsMultiSchema WITHOUT LOGIN 
GO 
CREATE SCHEMA MultiSchema1 AUTHORIZATION OwnsMultiSchema 
GO 
CREATE SCHEMA MultiSchema2 AUTHORIZATION OwnsMultiSchema 
GO 

CREATE USER OwnsOtherSchema WITHOUT LOGIN 
GO 
CREATE SCHEMA OtherSchema AUTHORIZATION OwnsOtherSchema 
GO 

CREATE TABLE MultiSchema1.T1 (foo int) 
GO 
CREATE TABLE MultiSchema2.T2 (foo int) 
GO 
CREATE TABLE OtherSchema.TA (foo int) 
GO 

CREATE PROC MultiSchema1.P1 
AS 
SELECT * FROM MultiSchema1.T1 
SELECT * FROM MultiSchema2.T2 
SELECT * FROM OtherSchema.TA 
Go 
EXEC AS USER = 'OwnsMultiSchema' 
GO 
--gives error on OtherSchema 
EXEC MultiSchema1.P1 
GO 
REVERT 
GO 

CREATE PROC OtherSchema.PA 
AS 
SELECT * FROM MultiSchema1.T1 
SELECT * FROM MultiSchema2.T2 
SELECT * FROM OtherSchema.TA 
Go 
GRANT EXEC ON OtherSchema.PA TO OwnsMultiSchema 
GO 
EXEC AS USER = 'OwnsMultiSchema' 
GO 
--works 
EXEC OtherSchema.PA 
GO 
REVERT 
GO 

संपादित करें 2:

  • हम "पार डेटाबेस स्वामित्व श्रृंखलन" का उपयोग नहीं करते
  • पंक्ति स्तर की सुरक्षा एक रेड हेरिंग और अप्रासंगिक है: हम इसे हर जगह का उपयोग नहीं करते
+2

क्या स्पष्टता के लिए वर्णन कर रहे अलग स्कीमा परिदृश्य का एक कोडित उदाहरण प्रदान करना संभव होगा? अपने परिदृश्य में, क्या दो अलग-अलग स्कीमा में एक ही मालिक है? –

+0

सर्वरफॉल्ट के लिए वोट क्यों बंद करें? यह कोड बंदरों के लिए है, sysadmins नहीं ... – gbn

+0

@ जॉन संसॉम: हाँ मैं करूँगा। – gbn

उत्तर

21

मुझे डर है कि या तो अपने वर्णन या स्वामित्व Chaining के अपने गर्भाधान स्पष्ट नहीं है, तो मुझे उस के साथ शुरू करते हैं:

"स्वामित्व Chaining" बस उस तथ्य को दर्शाता है कि जब एक संग्रहीत प्रक्रिया (या देखें) पर क्रियान्वित एसक्यूएल सर्वर, वर्तमान में निष्पादित बैच एसक्यूएल कोड को निष्पादित करते समय एसपीआरओ के मालिक (या एसप्रोक के स्कीमा के मालिक) के अधिकार/अनुमतियों को अस्थायी रूप से प्राप्त करता है। तो एसप्रोक के मामले में, उपयोगकर्ता उन निजी लोगों का उपयोग कुछ भी करने के लिए नहीं कर सकता है जो एसपीआरओ कोड उनके लिए लागू नहीं होता है। ध्यान दें कि यह कभी भी मालिक की पहचान प्राप्त नहीं करता है, केवल इसका अधिकार है, अस्थायी रूप से (हालांकि, इस तरह से निष्पादित करें ... यह करता है)।

तो सुरक्षा के लिए यह लाभ उठाने के लिए ठेठ दृष्टिकोण के लिए है:

  1. अपने स्वयं के स्कीमा में (और साथ ही और सभी गैर सुरक्षा दृश्य) डेटा टेबल्स के सभी रखो, इसे कहते हैं [डेटा जाने ] (हालांकि आम तौर पर [डीबीओ] का उपयोग किया जाता है क्योंकि यह पहले से ही है और उपयोगकर्ता की स्कीमा के लिए भी बहुत विशेषाधिकार प्राप्त है)। सुनिश्चित करें कि कोई मौजूदा उपयोगकर्ता, स्कीमा या मालिकों के पास इस [डेटा] स्कीमा तक पहुंच नहीं है।

  2. सभी sProcs (और/या संभवतः किसी भी सुरक्षा दृश्य) के लिए [exec] नामक स्कीमा बनाएं। सुनिश्चित करें कि इस स्कीमा के मालिक के पास [डेटा] स्कीमा तक पहुंच है (यदि आप इस स्कीमा के मालिक को डबो बनाते हैं तो यह आसान है)।

  3. "उपयोगकर्ता" नामक एक नई डीबी-रोल बनाएं और इसे [exec] स्कीमा तक पहुंच प्रदान करें। अब सभी उपयोगकर्ताओं को इस भूमिका में जोड़ें। सुनिश्चित करें कि आपके उपयोगकर्ताओं के पास केवल कनेक्ट अधिकार हैं और [dbo] सहित किसी भी अन्य स्कीमा तक पहुंच प्रदान नहीं है।

अब आपके उपयोगकर्ता केवल [exec] में sProcs निष्पादित करके डेटा तक पहुंच सकते हैं। वे किसी अन्य डेटा तक नहीं पहुंच सकते हैं या किसी अन्य ऑब्जेक्ट को निष्पादित नहीं कर सकते हैं।

मुझे यकीन नहीं है कि यह आपके प्रश्न का उत्तर देता है (क्योंकि मुझे अनिश्चितता थी कि सवाल वास्तव में क्या था), इसलिए मुझे रीडायरेक्ट करने में संकोच न करें।

  1. मैं हमेशा कि दर्पण चादर दृश्य की एक श्रृंखला के रूप में पंक्ति-स्तर सुरक्षा लागू:


    पंक्ति-स्तर सुरक्षा का सवाल है, यहाँ कैसे मैं हमेशा ऊपर सुरक्षा योजना के साथ यह करना है प्रत्येक तालिका और पंक्ति में सुरक्षा कोड से की गई एक सुरक्षा सूची में उपयोगकर्ता की पहचान (आमतौर पर Suser_Sname() या दूसरों में से एक के साथ) की तुलना करें। ये सुरक्षा-दृश्य हैं।

  2. [पंक्तियों] नामक एक नई स्कीमा बनाएं, इसे मालिक [डेटा] स्कीमा तक पहुंच दें और कुछ और नहीं। इस स्कीमा में सभी सुरक्षा-दृश्य रखें।

  3. [exec] मालिक की पहुंच [डेटा] स्कीमा तक पहुंच को रद्द करें और इसके बजाय इसे [पंक्तियों] स्कीमा तक डेटा पहुंच प्रदान करें।

हो गया। अब पंक्ति-स्तर सुरक्षा को पारदर्शी रूप से sProcs और तालिकाओं के बीच फिसलने के द्वारा कार्यान्वित किया गया है।


अंत में, यहाँ एक संग्रहीत की खरीद है कि मैं मदद करने के लिए मुझे याद इस अस्पष्ट सुरक्षा सामान काम करता है का कितना उपयोग करें और (उफ़, कोड की सही संस्करण) ही साथ सूचना का आदान:

CREATE proc [TestCnxOnly].[spShowProc_Security_NoEX] as 
--no "With Execute as Owner" for this version 
--create User [UserNoLogin] without login 
--Grant connect on database :: TestSecurity to Guest 
--alter database TestSecurity set trustworthy on 

--Show current user context: 
select current_user as current_ 
, session_user as session 
, user_name() as _name 
, suser_name() as [suser (sproc)] 
, suser_sname() as sname 
, system_user as system_ 


--Execute As Login = 'UserNoLogin' 
select current_user as current_ 
, session_user as session 
, user_name() as _name 
, suser_name() as [suser (after exec as)] 
, suser_sname() as sname 
, system_user as system_ 

EXEC('select current_user as current_ 
, session_user as session 
, user_name() as _name 
, suser_name() as [suser (in Exec(sql))] 
, suser_sname() as sname 
, system_user as system_') 

EXEC sp_ExecuteSQL N'select current_user as current_ 
, session_user as session 
, user_name() as _name 
, suser_name() as [suser (in sp_Executesql)] 
, suser_sname() as sname 
, system_user as system_' 

--Revert 
select current_user as current_ 
, session_user as session 
, user_name() as _name 
, suser_name() as [suser (aftr revert)] 
, suser_sname() as sname 
, system_user as system_ 

[संपादित करें: कोड का सही संस्करण)

+0

नहीं करना चाहता हूं, मैं आम तौर पर इस उदाहरण से स्वामित्व श्रृंखला को समझता हूं: स्कीमा 1 = टेबल अधिकारों (डेनी सहित) में स्कीमा 1 एक्सेस टेबल में एक संग्रहित प्रो चेक नहीं की गई है। कहें, कहें, schema2 की जांच की जाती है। मेरा उदाहरण दिखाता है कि EXEC MultiSchema1.P1 – gbn

+0

के साथ मेरा स्वयं का उदाहरण जो आपके उत्तर से पार हो गया है। मैं जो कुछ खो रहा था वह यह है कि यदि प्रासंगिक स्कीमा का * मालिक * समान है, तो अधिकारों की जांच नहीं की जाती है। यह तब उपयोगकर्ता/स्कीमा अलगाव का अर्थ है जिसे मुझे वास्तव में पढ़ना चाहिए था। हालांकि, हमारे पास पूर्व एसक्यूएल 2005 ओवरहैंग है और इसे – gbn

+0

के माध्यम से नहीं सोचा है कि यह उदाहरण काम करता है क्योंकि यह एक ही स्कीमा में है, इस प्रकार संग्रहीत प्रो और तालिका में एक ही मालिक है, इस प्रकार एक्सेस की अनुमति है क्योंकि मालिक के पास हमेशा * डिफ़ॉल्ट * अपने सामान के लिए अधिकारों का उपयोग करें। ध्यान दें, हालांकि, यह डेनी से अलग नहीं है, इत्यादि। जो कुछ भी स्कीमा के मालिक को रोक सकता है वह निश्चित रूप से संग्रहीत प्रोसेस को रोक देगा जो उनके पास भी है। – RBarryYoung

4

आप कर सकते हैं:

Grant Execute On Schema::[schema_name] To [user_name] 

उपयोगकर्ता स्कीमा में किसी भी प्रक्रियाओं पर अमल करने की अनुमति के लिए। यदि आप नहीं चाहते हैं कि वह उन सभी को निष्पादित करने में सक्षम हो, तो आप स्पष्ट रूप से उपयोगकर्ता को किसी विशेष प्रक्रिया पर निष्पादित करने से इंकार कर सकते हैं। इस मामले में इनकार करना प्राथमिकता होगी।

+0

सही है, लेकिन संग्रहित प्रक्रियाओं द्वारा उपयोग किए जाने वाले विभिन्न स्कीमा में तालिकाओं के बारे में क्या? मैं किसी भी अधिकार को – gbn

8

मेरा 2 सी: स्वामित्व श्रृंखला विरासत है। यह उन दिनों से होता है जब कोई विकल्प नहीं था, और आज के विकल्पों की तुलना में असुरक्षित और मोटे हैं।

मुझे लगता है कि विकल्प स्कीमा अनुमति नहीं है, विकल्प कोड हस्ताक्षर है। कोड हस्ताक्षर के साथ आप प्रक्रिया के हस्ताक्षर पर आवश्यक अनुमतियां दे सकते हैं, और डेटा एक्सेस को कड़ाई से नियंत्रित करते समय प्रक्रिया पर व्यापक निष्पादन पहुंच प्रदान कर सकते हैं। कोड हस्ताक्षर अधिक बारीक और अधिक सटीक नियंत्रण प्रदान करता है, और स्वामित्व श्रृंखला के तरीके से इसका दुरुपयोग नहीं किया जा सकता है। यह स्कीमा के अंदर काम करता है, यह स्कीमा में काम करता है, यह डेटाबेस में काम करता है और इसे खोलने के लिए क्रॉस डेटाबेस स्वामित्व श्रृंखला के विशाल सुरक्षा छेद की आवश्यकता नहीं होती है। और इसे एक्सेस उद्देश्यों के लिए ऑब्जेक्ट स्वामित्व के अपहरण की आवश्यकता नहीं है: प्रक्रिया का स्वामी कोई उपयोगकर्ता हो सकता है।

पंक्ति स्तर सुरक्षा के बारे में आपके दूसरे प्रश्न के लिए: इंजन स्तर की पेशकश की गई सुविधा के रूप में पंक्ति स्तर सुरक्षा वास्तव में SQL सर्वर संस्करण 2014 और पहले में मौजूद नहीं है। आपके पास विभिन्न कामकाज हैं, और वे कामकाज स्वामित्व श्रृंखला के मुकाबले कोड हस्ताक्षर के साथ वास्तव में बेहतर काम करते हैं। चूंकि sys.login_token में संदर्भ हस्ताक्षर और काउंटरसिग्नेचर शामिल हैं, इसलिए आप स्वामित्व श्रृंखला के संदर्भ में वास्तव में अधिक जटिल जांच कर सकते हैं।

संस्करण 2016 के बाद से SQL सर्वर पूरी तरह से row level security का समर्थन करता है।

+0

पंक्ति स्तर सुरक्षा वास्तव में एक लाल हेरिंग है .. हम सुरक्षा नियंत्रण से जॉइन के माध्यम से एक्सेस को नियंत्रित करने के लिए भी SUSER_SNAME का उपयोग करते हैं। – gbn

+0

यह "विरासत" बिट है और फिर समय/प्रयास/आलस्य क्यों मैंने पीछा नहीं किया है। वैसे भी + 1। धन्यवाद – gbn

संबंधित मुद्दे