一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - Oracle - oracle 虛擬專用數(shù)據(jù)庫詳細(xì)介紹

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

2020-03-11 16:49sunansheng Oracle

這篇文章詳細(xì)介紹了oracle 虛擬專用數(shù)據(jù)庫,對行級別和列級別分別舉了代碼實(shí)例并進(jìn)行分析,內(nèi)容比較詳細(xì),需要的朋友可以參考下。

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

行級別:在該級別下,可以控制某些用戶只能查看到某些數(shù)據(jù)行。比如,對于銷售數(shù)據(jù)表sales 來說,每個銷售人員只能檢索出他自己的銷售數(shù)據(jù),不能查詢其他銷售人員的銷售數(shù)據(jù)。

列級別:在該級別下,可以控制某些用戶不能檢索某個表的某個列的值。比如用戶HR 下的 employees 表中,含有工資(salary)列,由于該列比較敏感,因此不讓其他用戶查詢該列的值。 其他用戶檢索該列時,會發(fā)現(xiàn)其值全都為空(null )。

一、基于行的VPD 

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

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

?
1
Select * from sales_list ;

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

?
1
Select * from sales_list where seller_id='S0020';

對用戶來說,這個添加 where條件的過程是完全透明的,用戶并不知道 Oracle 已經(jīng)改寫了他發(fā)出的SQL 語句,從而過濾了查詢結(jié)果。當(dāng)然,如果該銷售人員發(fā)出的語句為:

?
1
Select * from sales_list where values>1000 ;

那么,當(dāng)Oracle 在改寫該 SQL 語句時,則會改寫為如下形式:

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

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

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

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

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

?
1
2
3
4
5
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)用程序上下文,如下所示:

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

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

?
1
SQL> drop context sales _ctx;

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

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

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

?
1
2
3
4
5
6
7
8
9
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包,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL> connect oe/oe
SQL> create or replace package sales_app_pkg is
 procedure set_sales_context;
 3 end
 4 /
SQL> create or replace package body sales_app_pkg is
 procedure set_sales_context is
 begin
 4  dbms_session.set_context('sales_ctx','seller_id',user);
 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)限賦給所有用戶以后,我們可以測試應(yīng)用程序上下文是否生效了。

?
1
2
3
4
5
6
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)用程序上下文生效了。接下來,我們創(chuàng)建用于FGAC 規(guī)則的函數(shù)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SQL> create or replace package sales_app_pkg is
 procedure set_sales_context;
 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;
 
 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ù)會為 FGAC 規(guī)則返回限定條件。這種 FGAC 規(guī)則函數(shù)必須具有兩個傳入?yún)?shù),第一個參數(shù)表示 schema 名稱,第二個參數(shù)表示表的名稱。表示對哪 個schema 下的哪個表添加FGAC 規(guī)則。同時必須返回字符型的值,該返回值會被Oracle 自動添加到 SQL 語句中的where條件部分。不過函數(shù)名稱和參數(shù)名稱可以按照需要進(jìn)行指定。從這里定義的函數(shù) 體中可以看出,如果登錄的用戶名以S 開頭,則會受到FGAC 規(guī)則的限制,where 條件里會添加 seller_id='Sxxxx' ,Sxxxx 表示登錄的用戶名。否則,如果以其他用戶的身份登錄,則不會受到FGAC規(guī)則的限制。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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 程序包來創(chuàng)建 FGAC 規(guī)則。我們?yōu)橛脩?OE下的sales_list 表創(chuàng)建了 規(guī)則;該規(guī)則利用用戶 OE下的sales_app_pkg.where_condition 函數(shù)返回 where條件;該規(guī)則作用的 SQL 語句類型為select 和update ;update_check 參數(shù)說明是否對更新以后的結(jié)果判斷是否滿足 FGAC 規(guī)則; 在創(chuàng)建規(guī)則的同時,我們也啟用該規(guī)則(enable 設(shè)置為true )。

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

?
1
2
3
4
5
6
7
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)在,我們可以開始測試FGAC 規(guī)則的效果了。

?
1
2
3
4
5
6
7
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

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

?
1
2
3
4
5
6
7
8
9
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

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

?
1
2
3
4
5
6
7
8
9
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

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

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

?
1
2
3
4
5
6
7
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 

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL> connect hr/hr
SQL> create or replace function hr_col_vpd
 2 (p_owner in varchar2,p_obj in varchar2)
 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)建了一個規(guī)則函數(shù)。與 FGAC 規(guī)則一樣,該函數(shù)必須有兩個傳入?yún)?shù),第一個表示 要限定的表所屬的schema 名稱,第二個表示要限定的表的名稱。在該函數(shù)中,我們定義,如果登錄用 戶為表的屬主,則可以查看所有列;否則,登錄用戶不是表所屬的用戶,則不能查看指定列。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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 存儲過程。 在這里,我們定義了一個名為 hr_emp_col_policy 的政策。該政策作用在用戶 HR下的employees 表上; 采用的政策函數(shù)為用戶HR下的hr_col_vpd 。
與FGAC 政策不同的是,我們需要指定另外兩個參數(shù):sec_relevant_cols表示要屏蔽的列的名稱, 可以指定多個列,列與列之間用逗號隔開;sec_relevant_cols_opt 設(shè)置為all_rows,則說明對 employees 表里所有的記錄都屏蔽salary 列。

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

?
1
2
3
4
5
6
7
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 列都顯示出來了。然后以用戶OE的身份登錄,執(zhí)行下面的SQL 語句:

?
1
2
3
4
5
6
7
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

很明顯,對于用戶OE來說,salary 列已經(jīng)被屏蔽了。

總結(jié)

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

原文鏈接:http://blog.csdn.net/sunansheng/article/details/52587044

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 午夜精品免费 | 日韩理论在线观看 | 日本一区二区精品88 | 高清国产欧美一v精品 | 黄色a∨ | 日本中文字幕一区二区三区不卡 | 欧美日韩成人在线 | 欧美一区二区三区综合色视频 | 国产精品拍拍拍福利在线观看 | 欧美日韩国产成人综合在线影院 | h网站国产| tube4欧美4 | 嫩草影院地址一地址二 | 精品国产三级av在线 | 草草视频人人爽 | 小仙夜晚慰自催眠mp3护士篇 | 日韩国产欧美视频 | 日本精品欧洲www | 边摸边吃奶边做爽视频免费 | 免费午夜剧场 | 日本一区二区三区久久精品 | 高清女主播一区二区三区 | 超兴奋朋友的中文字幕下 | 掰开逼操 | 1024在线视频精品免费 | 暖暖免费高清完整版观看日本 | 国内精品久久久久久不卡影院 | 国产精品日本一区二区三区在线看 | 国产精品自拍一区 | 久久内在线视频精品mp4 | ass日本乱妇ass | 搓光美女衣 | 男人j放进女人的p视频免费 | 99九九精品免费视频观看 | 青青青国产在线观看 | 色中色破解版 | 情侣奴伺候女王第2部分小说 | 欧美一级xxxx俄罗斯一级 | 呜嗯啊野战h呻吟男男双性 污小说在线阅读 | 日本特级a禁片在线播放 | 91精品天美精东蜜桃传媒免费 |