a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁(yè) > 數(shù)據(jù)庫(kù) > Oracle > 正文

oracle 虛擬專(zhuān)用數(shù)據(jù)庫(kù)詳細(xì)介紹

2024-08-29 14:00:33
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

所謂虛擬專(zhuān)用數(shù)據(jù)庫(kù)(VPD)指的是,通過(guò)在數(shù)據(jù)庫(kù)里進(jìn)行配置,從而讓不同的用戶(hù)只能查看某個(gè)表里的部分?jǐn)?shù)據(jù)。VPD分為以下兩個(gè)級(jí)別。

行級(jí)別:在該級(jí)別下,可以控制某些用戶(hù)只能查看到某些數(shù)據(jù)行。比如,對(duì)于銷(xiāo)售數(shù)據(jù)表sales 來(lái)說(shuō),每個(gè)銷(xiāo)售人員只能檢索出他自己的銷(xiāo)售數(shù)據(jù),不能查詢(xún)其他銷(xiāo)售人員的銷(xiāo)售數(shù)據(jù)。

列級(jí)別:在該級(jí)別下,可以控制某些用戶(hù)不能檢索某個(gè)表的某個(gè)列的值。比如用戶(hù)HR 下的 employees 表中,含有工資(salary)列,由于該列比較敏感,因此不讓其他用戶(hù)查詢(xún)?cè)摿械闹怠?其他用戶(hù)檢索該列時(shí),會(huì)發(fā)現(xiàn)其值全都為空(null )。

一、基于行的VPD 

基于行的VPD 也叫作Fine-Grained Access Control ,簡(jiǎn)稱(chēng) FGAC 。FGAC 通過(guò)定義規(guī)則實(shí)現(xiàn),規(guī)則 的集合叫做FGAC 政策(policy)。如果對(duì)某個(gè)表設(shè)置了 FGAC ,則當(dāng)用戶(hù)對(duì)該表發(fā)出查詢(xún)或者DML 語(yǔ)句時(shí),Oracle 都會(huì)根據(jù)定義的 FGAC 政策,而自動(dòng)改寫(xiě)這些SQL 語(yǔ)句。其改寫(xiě)方式為自動(dòng)在SQL 語(yǔ)句后面添加where條件。

比如,我們?cè)贠E用戶(hù)下有一個(gè)表sales_list ,存放了所有的銷(xiāo)售記錄。每個(gè)銷(xiāo)售人員只能查詢(xún)他 自己的銷(xiāo)售記錄。于是,我們?cè)趕ales 表上設(shè)置FGAC 政策來(lái)實(shí)現(xiàn)這個(gè)業(yè)務(wù)需求。如果某個(gè)銷(xiāo)售人員 (假設(shè)其登錄的用戶(hù)名為 S0020 )發(fā)出下面的查詢(xún)語(yǔ)句:

Select * from sales_list ; 

當(dāng)Oracle 在執(zhí)行該語(yǔ)句時(shí),如果發(fā)現(xiàn) sales_list 表上存在FGAC 政策,于是就會(huì)根據(jù) FGAC 政策,按照如下方式改寫(xiě)該SQL 語(yǔ)句:

Select * from sales_list where seller_id='S0020'; 

對(duì)用戶(hù)來(lái)說(shuō),這個(gè)添加 where條件的過(guò)程是完全透明的,用戶(hù)并不知道 Oracle 已經(jīng)改寫(xiě)了他發(fā)出的SQL 語(yǔ)句,從而過(guò)濾了查詢(xún)結(jié)果。當(dāng)然,如果該銷(xiāo)售人員發(fā)出的語(yǔ)句為:

Select * from sales_list where values>1000 ; 

那么,當(dāng)Oracle 在改寫(xiě)該 SQL 語(yǔ)句時(shí),則會(huì)改寫(xiě)為如下形式:

Select * from sales_list where qty_sold>1000 and seller_id='S0020'; 

使用FGAC 政策來(lái)限定返回記錄的方式具有許多優(yōu)點(diǎn)。比如,不需要改寫(xiě)應(yīng)用程序、對(duì)用戶(hù)完全透明、集中設(shè)置、便于管理等。

在使用FGAC 時(shí),會(huì)涉及應(yīng)用程序上下文(Application Context)的概念,使用應(yīng)用程序上下文可 以簡(jiǎn)化FGAC 的實(shí)現(xiàn)。應(yīng)用程序上下文是一個(gè)數(shù)據(jù)庫(kù)對(duì)象,可以把它理解為數(shù)據(jù)庫(kù)里的每個(gè) session 的全局環(huán)境變量。一旦用戶(hù)登錄到數(shù)據(jù)庫(kù),從而創(chuàng)建出session 以后,應(yīng)用程序上下文就在整個(gè) session 的生命周期里可用。在應(yīng)用程序上下文里可以定義多個(gè)屬性,并為這些屬性設(shè)置具體的值。而用戶(hù)不 能直接修改屬性的值,只能通過(guò)程序包來(lái)修改屬性值。應(yīng)用程序上下文總是由用戶(hù)sys 擁有。

比如,對(duì)于前面 sales_list 表的例子來(lái)說(shuō)。我們可以創(chuàng)建一個(gè)應(yīng)用程序上下文,當(dāng)用戶(hù)登錄時(shí),將 該用戶(hù)的ID 號(hào)作為一個(gè)屬性值放入該應(yīng)用程序上下文中。然后在定義FGAC 政策的時(shí)候,將該用戶(hù) ID號(hào)取出,并作為限定條件短語(yǔ)(也就是where條件語(yǔ)句)返回給 Oracle,從而實(shí)現(xiàn)FGAC 。

在Oracle 數(shù)據(jù)庫(kù)里,已經(jīng)為每個(gè) session 都預(yù)先建立了一個(gè)應(yīng)用程序上下文:userenv。一旦建立了session ,該 session 就可以使用這個(gè)應(yīng)用程序上下文。在 userenv中已經(jīng)預(yù)先定義了一些屬性,比如 ip_address、session_user和db_name 等。在獲取應(yīng)用程序上下文里的屬性值時(shí),我們使用sys_context 函數(shù)。該函數(shù)包含兩個(gè)參數(shù),第一個(gè)參數(shù)表示應(yīng)用程序上下文的名稱(chēng),第二個(gè)參數(shù)表示要顯示的屬性 名稱(chēng)。如下所示:

SQL> select sys_context('userenv','ip_address') "IP",    sys_context('userenv','db_name') "DB" from dual; IP           DB ---------------   --------- 152.68.32.60     ora10g 

我們也可以創(chuàng)建自己的應(yīng)用程序上下文,如下所示:

SQL> create or replace context sales_ctx using oe.sales_app_pkg; 

在這里,sales_ctx 是應(yīng)用程序上下文的名稱(chēng),而 sales_app_pkg 則是用來(lái)設(shè)置sales_ctx 里屬性的程序包。在創(chuàng)建應(yīng)用程序上下文時(shí),指定的、用來(lái)設(shè)置其中屬性的程序包可以不必事先存在。但是在為應(yīng)用程序上下文里設(shè)定屬性值時(shí),該程序包必須存在,否則報(bào)錯(cuò)。如果要?jiǎng)h除應(yīng)用程序上下文,則使用下面的命令:

SQL> drop context sales _ctx; 

創(chuàng)建了應(yīng)用程序上下文以后,我們就可以在其中設(shè)置屬性了。在設(shè)置具體的應(yīng)用程序上下文屬性時(shí),必須使用Oracle 提供的程序包 dbms_session.set_context 來(lái)設(shè)置其屬性。其使用格式為: 

dbms_session.set_context ('context_name', 'attribute_name', 'attribute_value') 

我們只能在程序包里使用dbms_session.set_context,而不能直接在SQL*Plus里調(diào)用。如下所示: 

SQL> show user USER is "SYS" SQL> exec dbms_session.set_context('sales_ctx','seller_id','S0020'); BEGIN dbms_session.set_context('sales_ctx','seller_id','S0020'); END; * ERROR at line 1: ORA-01031: insufficient privileges ORA-06512: at "SYS.DBMS_SESSION", line 90 ORA-06512: at line 1 

我們創(chuàng)建oe.sales_app_pkg包,如下所示:

SQL> connect oe/oe SQL> create or replace package sales_app_pkg is  2  procedure set_sales_context;  3 end;   4 / SQL> create or replace package body sales_app_pkg is  2  procedure set_sales_context is  3  begin  4  dbms_session.set_context('sales_ctx','seller_id',user);  5  end;  6 end;  7 / SQL> grant select on sales_list to public; SQL> grant update on sales_list to public; SQL> grant execute on sales_app_pkg to public; 

把執(zhí)行oe.sales_app_pkg 程序包的權(quán)限賦給所有用戶(hù)以后,我們可以測(cè)試應(yīng)用程序上下文是否生效了。

SQL> connect hr/hr SQL> exec oe.sales_app_pkg.set_sales_context; SQL> select sys_context('sales_ctx','seller_id') from dual; SYS_CONTEXT('SALES_CTX','SELLER_ID') -------------------------------------------------------------------------------- HR 

可以看到,應(yīng)用程序上下文生效了。接下來(lái),我們創(chuàng)建用于FGAC 規(guī)則的函數(shù)。

SQL> create or replace package sales_app_pkg is  2  procedure set_sales_context;  3  function where_condition  4  (p_schema_name varchar2,p_tab_name varchar2)  5   return varchar2;  6 end;  7 /  SQL> create or replace package body sales_app_pkg is  2 procedure set_sales_context is  3   v_user varchar2(30);  4 begin  5  dbms_session.set_context('sales_ctx','seller_id',user);  6 end;  7   8 function where_condition  9 (p_schema_name varchar2,p_tab_name varchar2) return varchar2 is  10  v_seller_id varchar2(100) := upper(sys_context('sales_ctx','seller_id'));  11  v_where_condition varchar2(2000);  12 begin  13  if v_seller_id like 'S%' then  14   v_where_condition := 'seller_id = ' || '''' || v_seller_id || '''';  15  else  16   v_where_condition := null;  17  end if;  18  return v_where_condition;  19 end;  20 end;  21 / 

在這里,我們主要關(guān)注 where_condition 函數(shù),該函數(shù)會(huì)為 FGAC 規(guī)則返回限定條件。這種 FGAC 規(guī)則函數(shù)必須具有兩個(gè)傳入?yún)?shù),第一個(gè)參數(shù)表示 schema 名稱(chēng),第二個(gè)參數(shù)表示表的名稱(chēng)。表示對(duì)哪 個(gè)schema 下的哪個(gè)表添加FGAC 規(guī)則。同時(shí)必須返回字符型的值,該返回值會(huì)被Oracle 自動(dòng)添加到 SQL 語(yǔ)句中的where條件部分。不過(guò)函數(shù)名稱(chēng)和參數(shù)名稱(chēng)可以按照需要進(jìn)行指定。從這里定義的函數(shù) 體中可以看出,如果登錄的用戶(hù)名以S 開(kāi)頭,則會(huì)受到FGAC 規(guī)則的限制,where 條件里會(huì)添加 seller_id='Sxxxx' ,Sxxxx 表示登錄的用戶(hù)名。否則,如果以其他用戶(hù)的身份登錄,則不會(huì)受到FGAC規(guī)則的限制。

創(chuàng)建了用于FGAC 規(guī)則的函數(shù)以后,我們開(kāi)始定義FGAC 規(guī)則。

SQL> connect / as sysdba SQL> begin  2  dbms_rls.add_policy(  3    OBJECT_SCHEMA=>'oe',  4    OBJECT_NAME=>'sales_list',  5    POLICY_NAME=>'oe_sales_list_fgac',  6    FUNCTION_SCHEMA=>'oe',  7    POLICY_FUNCTION=>'sales_app_pkg.where_condition',  8    STATEMENT_TYPES=>'select,update',  9    UPDATE_CHECK=>true,  10    ENABLE=>true);  11 end;  12 / 

如上所示,我們使用 dbms_rls 程序包來(lái)創(chuàng)建 FGAC 規(guī)則。我們?yōu)橛脩?hù) OE下的sales_list 表創(chuàng)建了 規(guī)則;該規(guī)則利用用戶(hù) OE下的sales_app_pkg.where_condition 函數(shù)返回 where條件;該規(guī)則作用的 SQL 語(yǔ)句類(lèi)型為select 和update ;update_check 參數(shù)說(shuō)明是否對(duì)更新以后的結(jié)果判斷是否滿足 FGAC 規(guī)則; 在創(chuàng)建規(guī)則的同時(shí),我們也啟用該規(guī)則(enable 設(shè)置為true )。

創(chuàng)建了FGAC 規(guī)則以后,我們需要在用戶(hù)登錄到應(yīng)用程序的時(shí)候,調(diào)用 sales_app_pkg  程序包里 的set_sales_context 存儲(chǔ)過(guò)程來(lái)設(shè)置該用戶(hù)的應(yīng)用程序上下文里的 seller_id 屬性的值。在實(shí)際應(yīng)用中, 我們可以在登錄界面上,當(dāng)用戶(hù)單擊登錄按鈕的時(shí)候進(jìn)行設(shè)置。在這里為了演示效果,我們創(chuàng)建一個(gè) 登錄觸發(fā)器來(lái)設(shè)置,如下所示:

SQL> connect / as sysdba SQL> create or replace trigger set_seller_id_on_logon  2 after logon on DATABASE  3 begin  4  oe.sales_app_pkg.set_sales_context;  5 end;  6 /  

現(xiàn)在,我們可以開(kāi)始測(cè)試FGAC 規(guī)則的效果了。

SQL> connect oe/oe SQL> select seller_id,count(*) from sales_list group by seller_id; SELLER_ID  COUNT(*) ---------  --------- S0010        1067 S0030        968 S0020        1465 

以用戶(hù)OE的身份登錄以后,可以看到,三個(gè)銷(xiāo)售人員各自的數(shù)據(jù)行數(shù)。然后以S0010 的身份登錄:

SQL> connect s0010/s0010 SQL> select sys_context('sales_ctx','seller_id') from dual; SYS_CONTEXT('SALES_CTX','SELLER_ID') --------------------------------------- S0010 SQL> select seller_id,count(*) from oe.sales_list group by seller_id; SELLER_ID  COUNT(*) ---------  --------- S0010        1067 

很明顯看到,我們?cè)O(shè)置的FGAC 規(guī)則生效了。我們繼續(xù)測(cè)試更新操作:

SQL> select seller_id,qty_sold from oe.sales_list where id=300; SELLER_ID  QTY_SOLD ---------  -------- S0010     1 SQL> update oe.sales_list set seller_id='S0020' where id=300; update oe.sales_list set seller_id='S0020' where id=300      * ERROR at line 1: ORA-28115: policy with check option violation 

由于我們?cè)趧?chuàng)建FGAC 規(guī)則時(shí),指定了update_check 為true ,當(dāng)用戶(hù) S0010 登錄以后更新sales_list 表,將 seller_id 從S0010 更新為S0020 時(shí)報(bào)錯(cuò),因?yàn)?S0010 無(wú)權(quán)查詢(xún)和修改不屬于他的銷(xiāo)售數(shù)據(jù)。如 果指定update_check 為false ,則允許這樣的update 語(yǔ)句成功。

FGAC 規(guī)則的使用是非常靈活的,其關(guān)鍵就在于 where_condition 函數(shù)的寫(xiě)法。如果要?jiǎng)h除 FGAC規(guī)則,則執(zhí)行下面的代碼:

SQL> begin  2  dbms_rls.drop_policy(  3    OBJECT_SCHEMA=>'oe',  4    OBJECT_NAME=>'sales_list',  5    POLICY_NAME=>'oe_sales_list_fgac');  6 end;  7 / 

二、基于列的VPD 

對(duì)于某些敏感列來(lái)說(shuō),比如員工的工資等,我們可以通過(guò)創(chuàng)建基于列的 VPD ,從而屏蔽這些敏感列,只有具有權(quán)限的用戶(hù)才能訪問(wèn)這些列。

基于列的VPD 與前面討論的FGAC 一樣,也是通過(guò)設(shè)置政策來(lái)實(shí)現(xiàn)的。設(shè)置基于列的VPD 時(shí),我們首先需要?jiǎng)?chuàng)建一個(gè)政策所需要用到的函數(shù),如下所示。

SQL> connect hr/hr SQL> create or replace function hr_col_vpd  2 (p_owner in varchar2,p_obj in varchar2)  3  return varchar2  4 is   5 l_ret  varchar2(2000);  6 begin  7   if (p_owner = USER) then  8    l_ret := NULL;  9   else  10    l_ret := '1=2';  11   end if;  12   return l_ret;  13 end;   14 / 

這里,我們創(chuàng)建了一個(gè)規(guī)則函數(shù)。與 FGAC 規(guī)則一樣,該函數(shù)必須有兩個(gè)傳入?yún)?shù),第一個(gè)表示 要限定的表所屬的schema 名稱(chēng),第二個(gè)表示要限定的表的名稱(chēng)。在該函數(shù)中,我們定義,如果登錄用 戶(hù)為表的屬主,則可以查看所有列;否則,登錄用戶(hù)不是表所屬的用戶(hù),則不能查看指定列。

至于具體哪些列要被屏蔽,則需要在定義政策時(shí)進(jìn)行指定,如下所示:

SQL> begin  2 dbms_rls.add_policy(object_schema=>'hr',  3 object_name=>'employees',  4 policy_name=>'hr_emp_col_policy',  5 function_schema=>'hr',  6 policy_function=>'hr_col_vpd',  7 statement_types=>'select',  8 sec_relevant_cols=>'salary',  9 sec_relevant_cols_opt => dbms_rls.all_rows  10 );  11 end;  12 / 

創(chuàng)建基于列VPD 與創(chuàng)建FGAC 政策一樣,也是使用dbms_rls 程序包里的add_policy 存儲(chǔ)過(guò)程。 在這里,我們定義了一個(gè)名為 hr_emp_col_policy 的政策。該政策作用在用戶(hù) HR下的employees 表上; 采用的政策函數(shù)為用戶(hù)HR下的hr_col_vpd 。
與FGAC 政策不同的是,我們需要指定另外兩個(gè)參數(shù):sec_relevant_cols表示要屏蔽的列的名稱(chēng), 可以指定多個(gè)列,列與列之間用逗號(hào)隔開(kāi);sec_relevant_cols_opt 設(shè)置為all_rows,則說(shuō)明對(duì) employees 表里所有的記錄都屏蔽salary 列。

我們以用戶(hù)HR的身份登錄,并顯示salary 列。

SQL> connect hr/hr SQL> select employee_id,last_name,salary from hr.employees where rownum<4; EMPLOYEE_ID  LAST_NAME      SALARY -----------  -------------    ------- 198        OConnell        2600 199        Grant          2600 200        Whalen         4400 

可以看到所有的salary 列都顯示出來(lái)了。然后以用戶(hù)OE的身份登錄,執(zhí)行下面的SQL 語(yǔ)句:

SQL> connect oe/oe SQL> select employee_id,last_name,salary from hr.employees where rownum<4; EMPLOYEE_ID  LAST_NAME      SALARY -----------  -------------    ------- 198        OConnell 199        Grant 200        Whalen 

很明顯,對(duì)于用戶(hù)OE來(lái)說(shuō),salary 列已經(jīng)被屏蔽了。

總結(jié)

以上就是本文關(guān)于oracle/92961.html">oracle 虛擬專(zhuān)用數(shù)據(jù)庫(kù)詳細(xì)介紹的全部?jī)?nèi)容,感興趣的朋友可以瀏覽本站其他相關(guān)專(zhuān)題,有什么問(wèn)題可以隨時(shí)留言,小編會(huì)及時(shí)回復(fù)大家。感謝朋友們對(duì)本站的支持!


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到oracle教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91麻豆精品国产91久久久资源速度 | 国产日韩一区二区三区 | 日韩综合在线 | 精品在线一区二区 | 国产精品.xx视频.xxtv | 亚洲伦理一区 | 久久99欧美| 色网址在线 | 亚洲精品乱码久久久久久按摩观 | 黄av在线 | 在线99热 | 久久综合久久久 | 亚洲成人免费在线 | 日韩在线资源 | 超碰免费在 | 国产在线视频在线 | 电影一区二区在线 | 欧美一区二区三区aa大片漫 | 亚洲精品自拍视频 | h视频在线免费观看 | 一区二区三区国产精品 | 四虎av在线 | 欧美一区二区三区精品 | 手机看片福利视频 | 日韩在线一 | h片在线免费观看 | 日韩久久一区二区 | 五月婷婷综合网 | 国产精品对白一区二区三区 | 国产精品亚洲第一区在线暖暖韩国 | 日本中文字幕在线播放 | 日本www高清| 精品久久中文字幕 | 国产一区 | 国产福利视频 | 日韩欧美中文字幕在线观看 | 国产区亚洲 | 成人在线小视频 | 午夜看看| 久草在线 | 成人精品一区二区三区中文字幕 |