सेवरनाइन का नोट:यह ब्लॉग मरणोपरांत प्रकाशित किया जा रहा है क्योंकि 16 जुलाई, 2018 को बेरेन्ड टोबर का निधन हो गया। हम PostgreSQL समुदाय में उनके योगदान का सम्मान करते हैं और अपने मित्र और अतिथि लेखक के लिए शांति की कामना करते हैं।
पिछले लेख में हमने पोस्टग्रेएसक्यूएल ट्रिगर और संग्रहीत कार्यों की मूल बातें पेश कीं और डेटा सत्यापन, परिवर्तन लॉगिंग, सम्मिलित डेटा से मूल्य प्राप्त करना, सरल अद्यतन योग्य दृश्यों के साथ डेटा छिपाना, सारांश डेटा बनाए रखना सहित छह उदाहरण उपयोग के मामले प्रदान किए। अलग-अलग तालिकाओं में, और उन्नत विशेषाधिकार पर कोड का सुरक्षित आह्वान। यह आलेख उस नींव पर आगे बढ़ता है और सीमित-विशेषाधिकार (यानी, गैर-सुपरयूज़र) भूमिकाओं के लिए लॉगिन क्रेडेंशियल प्रावधान को सौंपने की सुविधा के लिए एक ट्रिगर और संग्रहीत फ़ंक्शन का उपयोग करने वाली तकनीक प्रस्तुत करता है। इस सुविधा का उपयोग उच्च-मूल्य वाले सिस्टम-प्रशासन कर्मियों के लिए प्रशासनिक कार्यभार को कम करने के लिए किया जा सकता है। चरम पर ले जाया गया, हम लॉगिन क्रेडेंशियल्स के अनाम एंड-यूज़र स्व-प्रावधान को प्रदर्शित करते हैं, अर्थात, संभावित डेटाबेस उपयोगकर्ताओं को उचित-स्कोप्ड विशेषाधिकार स्तर पर निष्पादित एक संग्रहीत फ़ंक्शन के अंदर "डायनेमिक SQL" को लागू करके अपने आप लॉगिन क्रेडेंशियल का प्रावधान करने देते हैं। परिचयपी>
मददगार पृष्ठभूमि पढ़ना
अपने पोस्टग्रेएसक्यूएल डेटाबेस को कैसे सुरक्षित करें पर सेबस्टियन इंसॉस्टी के हालिया लेख में कुछ अत्यधिक प्रासंगिक युक्तियां शामिल हैं जिनसे आपको परिचित होना चाहिए, अर्थात्, क्लाइंट प्रमाणीकरण नियंत्रण, सर्वर कॉन्फ़िगरेशन, उपयोगकर्ता और भूमिका प्रबंधन, सुपर उपयोगकर्ता प्रबंधन, और पर युक्तियाँ # 1 - # 5। डेटा एन्क्रिप्शन। हम इस लेख में प्रत्येक टिप के कुछ हिस्सों का उपयोग करेंगे।
PostgreSQL विशेषाधिकार और उपयोगकर्ता प्रबंधन पर जोशुआ ओटवेल के एक अन्य हालिया लेख में होस्ट कॉन्फ़िगरेशन और उपयोगकर्ता विशेषाधिकारों का एक अच्छा उपचार भी है जो उन दो विषयों पर थोड़ा और विस्तार से बताता है।
नेटवर्क ट्रैफ़िक की सुरक्षा करना
प्रस्तावित फीचर में यूजर्स को डेटाबेस लॉगइन क्रेडेंशियल्स का प्रावधान करने की अनुमति शामिल है और ऐसा करते समय, वे नेटवर्क पर अपना नया लॉगिन नाम और पासवर्ड निर्दिष्ट करेंगे। इस नेटवर्क संचार की सुरक्षा आवश्यक है और इसे एन्क्रिप्टेड कनेक्शन के समर्थन और आवश्यकता के लिए PostgreSQL सर्वर को कॉन्फ़िगर करके प्राप्त किया जा सकता है। "ssl" सेटिंग द्वारा postgresql.conf फ़ाइल में ट्रांसपोर्ट लेयर सुरक्षा सक्षम है:
ssl = on
होस्ट-आधारित अभिगम नियंत्रण
वर्तमान मामले के लिए, हम pg_hba.conf फ़ाइल में एक होस्ट-आधारित एक्सेस कॉन्फ़िगरेशन लाइन जोड़ेंगे जो उपयोगकर्ता नाम का उपयोग करने वाले संभावित डेटाबेस उपयोगकर्ताओं की आबादी के लिए कुछ उपयुक्त उप-नेटवर्क से अनाम, यानी विश्वसनीय, डेटाबेस में लॉगिन करने की अनुमति देती है। "गुमनाम", और दूसरी कॉन्फ़िगरेशन लाइन जिसमें किसी अन्य लॉगिन नाम के लिए पासवर्ड लॉगिन की आवश्यकता होती है। याद रखें कि होस्ट कॉन्फ़िगरेशन पहले मैच का आह्वान करता है, इसलिए जब भी "अनाम" उपयोगकर्ता नाम निर्दिष्ट किया जाता है, तो पहली पंक्ति लागू होगी, विश्वसनीय (यानी, पासवर्ड की आवश्यकता नहीं) कनेक्शन की अनुमति होगी, और फिर बाद में जब भी कोई अन्य उपयोगकर्ता नाम निर्दिष्ट किया जाएगा तो पासवर्ड की आवश्यकता होगी। उदाहरण के लिए, यदि नमूना डेटाबेस "नमूनाब" का उपयोग केवल कर्मचारियों द्वारा और आंतरिक रूप से कॉर्पोरेट सुविधाओं के लिए किया जाना है, तो हम कुछ गैर-रूटेबल आंतरिक सबनेट के लिए विश्वसनीय पहुंच को कॉन्फ़िगर कर सकते हैं:
# TYPE DATABASE USER ADDRESS METHOD
hostssl sampledb anonymous 192.168.1.0/24 trust
hostssl sampledb all 192.168.1.0/24 md5
यदि डेटाबेस को आम तौर पर जनता के लिए उपलब्ध कराया जाना है, तो हम "किसी भी पते" पहुंच को कॉन्फ़िगर कर सकते हैं:
# TYPE DATABASE USER ADDRESS METHOD
hostssl sampledb anonymous all trust
hostssl sampledb all all md5
ध्यान दें कि उपरोक्त अतिरिक्त सावधानियों के बिना संभावित रूप से खतरनाक है, संभवतः एप्लिकेशन डिज़ाइन में या फ़ायरवॉल डिवाइस पर, इस सुविधा के उपयोग को सीमित करने के लिए, क्योंकि आप जानते हैं कि कुछ स्क्रिप्ट किडी केवल लुल्ज़ के लिए अंतहीन खाता निर्माण को स्वचालित कर देगी।
ध्यान दें कि हमने कनेक्शन प्रकार को "होस्टएसएसएल" के रूप में निर्दिष्ट किया है, जिसका अर्थ है कि टीसीपी/आईपी का उपयोग करके किए गए कनेक्शन तभी सफल होते हैं जब कनेक्शन एसएसएल एन्क्रिप्शन के साथ किया जाता है ताकि नेटवर्क ट्रैफिक को छिपाने से बचाया जा सके।
सार्वजनिक योजना को बंद करना
चूंकि हम संभावित रूप से अज्ञात (यानी, अविश्वसनीय) व्यक्तियों को डेटाबेस तक पहुंचने की इजाजत दे रहे हैं, इसलिए हम यह सुनिश्चित करना चाहेंगे कि डिफ़ॉल्ट पहुंच क्षमता सीमित है। एक महत्वपूर्ण उपाय डिफ़ॉल्ट सार्वजनिक स्कीमा ऑब्जेक्ट निर्माण विशेषाधिकार को निरस्त करना है ताकि डिफ़ॉल्ट स्कीमा विशेषाधिकारों से संबंधित हाल ही में प्रकाशित PostgreSQL भेद्यता को कम किया जा सके (cf. वास्तव में आपके द्वारा सार्वजनिक स्कीमा को लॉक करना)।
एक नमूना डेटाबेस
उदाहरण के लिए हम एक खाली नमूना डेटाबेस के साथ शुरुआत करेंगे:
create database sampledb;
\connect sampledb
revoke create on schema public from public;
alter default privileges revoke all privileges on tables from public;
हम पहले की pg_hba.conf सेटिंग के अनुरूप अनाम लॉगिन भूमिका भी बनाते हैं।
create role anonymous login
nosuperuser
noinherit
nocreatedb
nocreaterole
Noreplication;
और फिर हम एक अपरंपरागत दृष्टिकोण को परिभाषित करके कुछ नया करते हैं:
create or replace view person as
select
null::name as login_name,
null::name as login_pass;
यह दृश्य किसी तालिका का संदर्भ नहीं देता है और इसलिए एक चुनिंदा क्वेरी हमेशा एक खाली पंक्ति लौटाती है:
select * from person;
login_name | login_pass
------------+-------------
|
(1 row)
एक चीज जो हमारे लिए करती है, वह यह है कि एक खाता स्थापित करने के लिए कौन से डेटा की आवश्यकता है, इसके लिए अंतिम उपयोगकर्ताओं को दस्तावेज या संकेत प्रदान करना है। अर्थात्, तालिका को क्वेरी करके, भले ही परिणाम एक खाली पंक्ति हो, परिणाम दो डेटा तत्वों के नाम प्रकट करता है।
लेकिन इससे भी बेहतर, इस दृष्टिकोण का अस्तित्व आवश्यक डेटाटाइप के निर्धारण की अनुमति देता है:
\d person
View "public.person"
Column | Type | Modifiers
--------------+------+-----------
login_name | name |
login_pass | name |
हम एक संग्रहीत फ़ंक्शन और ट्रिगर के साथ क्रेडेंशियल प्रावधान कार्यक्षमता को लागू करेंगे, तो चलिए एक खाली फ़ंक्शन टेम्पलेट और संबंधित ट्रिगर घोषित करते हैं:
create or replace function person_iit()
returns trigger
set schema 'public'
language plpgsql
security definer
as '
begin
end;
';
create trigger person_iit
instead of insert
on person
for each row execute procedure person_iit();
ध्यान दें कि हम पिछले लेख से प्रस्तावित नामकरण परंपरा का पालन कर रहे हैं, संबंधित तालिका नाम का उपयोग करते हुए एक संक्षिप्त-हाथ संक्षिप्त नाम का उपयोग करते हुए तालिका और संग्रहीत फ़ंक्शन के बीच ट्रिगर संबंध की विशेषताओं को INSTEAD OF INSERT ट्रिगर के लिए (यानी, प्रत्यय " आईआईटी")। हमने स्टोर किए गए फ़ंक्शन में SCHEMA और SECURITY DEFINER विशेषताएँ भी जोड़ी हैं:पूर्व क्योंकि यह खोज पथ सेट करने के लिए अच्छा अभ्यास है जो फ़ंक्शन निष्पादन की अवधि के लिए लागू होता है, और बाद में भूमिका निर्माण की सुविधा के लिए, जो आमतौर पर एक डेटाबेस सुपरयुसर प्राधिकरण होता है। केवल लेकिन इस मामले में अनाम उपयोगकर्ताओं को प्रत्यायोजित किया जाएगा।
और अंत में हम क्वेरी और डालने के लिए न्यूनतम-पर्याप्त अनुमतियाँ जोड़ते हैं:
grant select, insert on table person to anonymous;
आज श्वेतपत्र डाउनलोड करें क्लस्टरकंट्रोल के साथ पोस्टग्रेएसक्यूएल प्रबंधन और स्वचालन इस बारे में जानें कि पोस्टग्रेएसक्यूएल को तैनात करने, मॉनिटर करने, प्रबंधित करने और स्केल करने के लिए आपको क्या जानना चाहिए। श्वेतपत्र डाउनलोड करें आइए समीक्षा करें
संग्रहीत फ़ंक्शन कोड को लागू करने से पहले, आइए देखें कि हमारे पास क्या है। पहले पोस्टग्रेज़ उपयोगकर्ता के स्वामित्व वाला नमूना डेटाबेस है:
\l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
sampledb | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
And there’s the user roles, including the database superuser and the newly-created anonymous login roles:
\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
anonymous | No inheritance | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
और हमारे द्वारा बनाया गया दृश्य है और पोस्टग्रेज़ उपयोगकर्ता द्वारा अनाम उपयोगकर्ता को दिए गए एक्सेस विशेषाधिकार बनाने और पढ़ने की एक सूची है:
\d
List of relations
Schema | Name | Type | Owner
--------+--------+------+----------
public | person | view | postgres
(1 row)
\dp
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
--------+--------+------+---------------------------+-------------------+----------
public | person | view | postgres=arwdDxt/postgres+| |
| | | anonymous=ar/postgres | |
(1 row)
अंत में, तालिका विवरण कॉलम नाम और डेटाटाइप के साथ-साथ संबंधित ट्रिगर दिखाता है:
\d person
View "public.person"
Column | Type | Modifiers
--------------+------+-----------
login_name | name |
login_pass | name |
Triggers:
person_iit INSTEAD OF INSERT ON person FOR EACH ROW EXECUTE PROCEDURE person_iit()
डायनामिक SQL
हम गतिशील एसक्यूएल को नियोजित करने जा रहे हैं, यानी, डीडीएल स्टेटमेंट के अंतिम फॉर्म को रन-टाइम पर आंशिक रूप से उपयोगकर्ता द्वारा दर्ज किए गए डेटा से, ट्रिगर फ़ंक्शन बॉडी को भरने के लिए। विशेष रूप से हम एक नई लॉगिन भूमिका बनाने और चर के रूप में विशिष्ट पैरामीटर भरने के लिए कथन की रूपरेखा को हार्ड कोड करते हैं।
इस कमांड का सामान्य रूप है
create role name [ [ with ] option [ ... ] ]
जहां विकल्प सोलह विशिष्ट गुणों में से कोई भी हो सकता है। आम तौर पर डिफ़ॉल्ट उपयुक्त होते हैं लेकिन हम कई सीमित विकल्पों के बारे में स्पष्ट होने जा रहे हैं और फ़ॉर्म का उपयोग करेंगे
create role name
with
login
inherit
nosuperuser
nocreatedb
nocreaterole
password ‘password’;
जहां हम रन टाइम पर उपयोगकर्ता द्वारा निर्दिष्ट भूमिका का नाम और पासवर्ड डालेंगे।
डायनामिक रूप से निर्मित बयानों को निष्पादित कमांड के साथ लागू किया जाता है:
execute command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
जो हमारी विशिष्ट आवश्यकताओं के लिए कुछ इस तरह दिखाई देगा
execute 'create role '
|| new.login_name
|| ' with login inherit nosuperuser nocreatedb nocreaterole password '
|| quote_literal(new.login_pass);
जहां उद्धरण_लिटरल फ़ंक्शन स्ट्रिंग तर्क को स्ट्रिंग अक्षर के रूप में उपयोग के लिए उपयुक्त रूप से उद्धृत करता है ताकि वाक्य रचनात्मक आवश्यकता का अनुपालन किया जा सके कि पासवर्ड वास्तव में उद्धृत किया जा सके ..
एक बार जब हमारे पास कमांड स्ट्रिंग बन जाती है, तो हम इसे ट्रिगर फ़ंक्शन के भीतर pl/pgsql निष्पादित कमांड के तर्क के रूप में आपूर्ति करते हैं।
इन सबको एक साथ रखने से ऐसा लगता है:
create or replace function person_iit()
returns trigger
set schema 'public'
language plpgsql
security definer
as $$
begin
-- note this is for demonstration only. it is vulnerable to sql injection.
execute 'create role '
|| new.login_name
|| ' with login inherit nosuperuser nocreatedb nocreaterole password '
|| quote_literal(new.login_pass);
return new;
end;
$$;
चलो इसे आजमाएं!
सब कुछ जगह पर है, तो चलिए इसे घुमाते हैं! पहले हम सत्र प्राधिकरण को अनाम उपयोगकर्ता पर स्विच करते हैं और फिर व्यक्ति दृश्य के विरुद्ध एक प्रविष्टि करते हैं:
set session authorization anonymous;
insert into person values ('alice', '1234');
परिणाम यह है कि सिस्टम तालिका में नया उपयोगकर्ता ऐलिस जोड़ा गया है:
\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
alice | | {}
anonymous | No inheritance | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
यह उपयोगकर्ता बॉब को जोड़ने के लिए psql क्लाइंट उपयोगिता के लिए एक SQL कमांड स्ट्रिंग को पाइप करके ऑपरेटिंग सिस्टम कमांड लाइन से सीधे काम करता है:
$ psql sampledb anonymous <<< "insert into person values ('bob', '4321');"
INSERT 0 1
$ psql sampledb anonymous <<< "\du"
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
alice | | {}
anonymous | No inheritance | {}
bob | | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
थोड़ा कवच लगाएं
ट्रिगर फ़ंक्शन का प्रारंभिक उदाहरण SQL इंजेक्शन हमले के लिए असुरक्षित है, अर्थात एक दुर्भावनापूर्ण खतरा अभिनेता इनपुट को क्राफ्ट कर सकता है जिसके परिणामस्वरूप अनधिकृत पहुंच होती है। उदाहरण के लिए, अनाम उपयोगकर्ता भूमिका के रूप में कनेक्ट होने पर, दायरे से बाहर कुछ करने का प्रयास उचित रूप से विफल हो जाता है:
set session authorization anonymous;
drop user alice;
ERROR: permission denied to drop role
लेकिन निम्न दुर्भावनापूर्ण इनपुट 'ईव' नामक एक सुपरयूज़र भूमिका बनाता है (साथ ही 'कैथी' नाम का एक फंदा खाता):
insert into person
values ('eve with superuser login password ''666''; create role cathy', '777');
\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
alice | | {}
anonymous | No inheritance | {}
cathy | | {}
eve | Superuser | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
फिर गुप्त सुपरयुसर भूमिका का उपयोग डेटाबेस में कहर बरपाने के लिए किया जा सकता है, उदाहरण के लिए उपयोगकर्ता खातों को हटाना (या इससे भी बदतर!):
\c - eve
drop user alice;
\du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
anonymous | No inheritance | {}
cathy | | {}
eve | Superuser | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
इस भेद्यता को कम करने के लिए, हमें इनपुट को साफ करने के लिए कदम उठाने चाहिए। उदाहरण के लिए, कोट_आइडेंट फ़ंक्शन को लागू करना, जो एक एसक्यूएल स्टेटमेंट में एक पहचानकर्ता के रूप में उपयोग के लिए उपयुक्त रूप से उद्धृत एक स्ट्रिंग देता है, जब आवश्यक होने पर उद्धरण जोड़े जाते हैं, जैसे कि स्ट्रिंग में गैर-पहचानकर्ता वर्ण होते हैं या केस-फोल्ड किया जाएगा, और ठीक से दोहरीकरण एम्बेडेड होगा उद्धरण:
create or replace function person_iit()
returns trigger
set schema 'public'
language plpgsql
security definer
as $$
begin
execute 'create role '
|| quote_ident(new.login_name)
|| ' with login inherit nosuperuser nocreatedb nocreaterole password '
|| quote_literal(new.login_pass);
return new;
end;
$$;
अब यदि उसी SQL इंजेक्शन शोषण को 'फ्रैंक' नामक एक और सुपरयूज़र बनाने का प्रयास किया जाता है, तो यह विफल हो जाता है, और परिणाम एक बहुत ही अपरंपरागत उपयोगकर्ता नाम है:
set session authorization anonymous;
insert into person
values ('frank with superuser login password ''666''; create role dave', '777');
\du
List of roles
Role name | Attributes | Member of
-----------------------+------------------------------------------------------------+----------
anonymous | No inheritance | {}
eve | Superuser | {}
frank with superuser | |
login password '666';| |
create role dave | |
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
हम ट्रिगर फ़ंक्शन के भीतर और अधिक समझदार डेटा सत्यापन लागू कर सकते हैं जैसे कि केवल अल्फा-न्यूमेरिक उपयोगकर्ता नाम की आवश्यकता होती है और सफेद स्थान और अन्य वर्णों को अस्वीकार करना:
create or replace function person_iit()
returns trigger
set schema 'public'
language plpgsql
security definer
as $$
begin
-- Basic input sanitization
if new.login_name is null then
raise exception 'null login_name disallowed';
elsif position(' ' in new.login_name) > 0 then
raise exception 'login_name whitespace disallowed';
elsif length(new.login_name) = 0 then
raise exception 'login_name must be non-empty';
elsif not (select new.login_name similar to '[A-Za-z]%') then
raise exception 'login_name must begin with a letter.';
end if;
if new.login_pass is null then
raise exception 'null login_pass disallowed';
elsif position(' ' in new.login_pass) > 0 then
raise exception 'login_pass whitespace disallowed';
elsif length(new.login_pass) = 0 then
raise exception 'login_pass must be non-empty';
end if;
-- Provision login credentials
execute 'create role '
|| quote_ident(new.login_name)
|| ' with login inherit nosuperuser nocreatedb nocreaterole password '
|| quote_literal(new.login_pass);
return new;
end;
$$;
और फिर पुष्टि करें कि विभिन्न स्वच्छता जांच काम करती हैं:
set session authorization anonymous;
insert into person values (NULL, NULL);
ERROR: null login_name disallowed
insert into person values ('gina', NULL);
ERROR: null login_pass disallowed
insert into person values ('gina', '');
ERROR: login_pass must be non-empty
insert into person values ('', '1234');
ERROR: login_name must be non-empty
insert into person values ('gi na', '1234');
ERROR: login_name whitespace disallowed
insert into person values ('1gina', '1234');
ERROR: login_name must begin with a letter.
चलो इसे एक पायदान ऊपर ले जाएं
मान लीजिए कि हम बनाई गई उपयोगकर्ता भूमिका से संबंधित अतिरिक्त मेटाडेटा या एप्लिकेशन डेटा संग्रहीत करना चाहते हैं, उदाहरण के लिए, शायद एक टाइम स्टैम्प और भूमिका निर्माण से जुड़ा स्रोत आईपी पता। निश्चित रूप से दृश्य इस नई आवश्यकता को पूरा नहीं कर सकता क्योंकि कोई अंतर्निहित भंडारण नहीं है, इसलिए एक वास्तविक तालिका की आवश्यकता है। साथ ही, आइए आगे मान लें कि हम अनाम लॉगिन भूमिका के साथ लॉग इन करने वाले उपयोगकर्ताओं से उस तालिका की दृश्यता को प्रतिबंधित करना चाहते हैं। हम तालिका को एक अलग नाम स्थान (यानी, एक PostgreSQL स्कीमा) में छिपा सकते हैं जो अनाम उपयोगकर्ताओं के लिए दुर्गम रहता है। आइए इस नाम स्थान को "निजी" नामस्थान कहते हैं और नाम स्थान में तालिका बनाते हैं:
create schema private;
create table private.person (
login_name name not null primary key,
inet_client_addr inet default inet_client_addr(),
create_time timestamptz default now()
);
ट्रिगर फ़ंक्शन के अंदर एक साधारण अतिरिक्त इंसर्ट कमांड इस संबंधित मेटाडेटा को रिकॉर्ड करता है:
create or replace function person_iit()
returns trigger
set schema 'public'
language plpgsql
security definer
as $$
begin
-- Basic input sanitization
if new.login_name is null then
raise exception 'null login_name disallowed';
elsif position(' ' in new.login_name) > 0 then
raise exception 'login_name whitespace disallowed';
elsif length(new.login_name) = 0 then
raise exception 'login_name must be non-empty';
elsif not (select new.login_name similar to '[A-Za-z]%') then
raise exception 'login_name must begin with a letter.';
end if;
if new.login_pass is null then
raise exception 'null login_pass disallowed';
elsif length(new.login_pass) = 0 then
raise exception 'login_pass must be non-empty';
end if;
-- Record associated metadata
insert into private.person values (new.login_name);
-- Provision login credentials
execute 'create role '
|| quote_ident(new.login_name)
|| ' with login inherit nosuperuser nocreatedb nocreaterole password '
|| quote_literal(new.login_pass);
return new;
end;
$$;
और हम इसे एक आसान परीक्षा दे सकते हैं। पहले हम पुष्टि करते हैं कि अनाम भूमिका के रूप में कनेक्ट होने पर केवल public.person दृश्य दिखाई देता है, न कि निजी.व्यक्ति तालिका:
set session authorization anonymous;
\d
List of relations
Schema | Name | Type | Owner
--------+--------+------+----------
public | person | view | postgres
(1 row)
select * from private.person;
ERROR: permission denied for schema private
और फिर एक नई भूमिका डालने के बाद:
insert into person values ('gina', '1234');
reset session authorization;
select * from private.person;
login_name | inet_client_addr | create_time
------------+------------------+-------------------------------
gina | 192.168.2.106 | 2018-06-24 07:56:13.838679-07
(1 row)
Private.person तालिका IP पते के लिए मेटाडेटा कैप्चर और पंक्ति डालने का समय दिखाती है।
निष्कर्ष
इस लेख में, हमने गैर-सुपरयूज़र भूमिकाओं के लिए PostgreSQL भूमिका क्रेडेंशियल प्रोविज़निंग को प्रत्यायोजित करने की एक तकनीक का प्रदर्शन किया है। जबकि उदाहरण पूरी तरह से अनाम उपयोगकर्ताओं को क्रेडेंशियल कार्यक्षमता को सौंपता है, एक समान दृष्टिकोण का उपयोग केवल विश्वसनीय कर्मियों को कार्यक्षमता को आंशिक रूप से सौंपने के लिए किया जा सकता है, जबकि अभी भी उच्च-मूल्य वाले डेटाबेस या सिस्टम व्यवस्थापक कर्मियों से इस काम को ऑफ-लोडिंग के लाभ को बरकरार रखा जा सकता है। हमने पोस्टग्रेएसक्यूएल स्कीमा का उपयोग करते हुए स्तरित डेटा एक्सेस की एक तकनीक का भी प्रदर्शन किया, चुनिंदा रूप से डेटाबेस ऑब्जेक्ट्स को उजागर या छुपाया। इस श्रृंखला के अगले लेख में हम एप्लिकेशन कार्यान्वयन के लिए एक नए डेटाबेस आर्किटेक्चर डिज़ाइन का प्रस्ताव करने के लिए स्तरित डेटा एक्सेस तकनीक पर विस्तार करेंगे।