91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

oracle虛擬專用數據庫的示例分析

發布時間:2021-07-28 14:05:22 來源:億速云 閱讀:128 作者:小新 欄目:數據庫

這篇文章給大家分享的是有關oracle虛擬專用數據庫的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

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

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

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

一、基于行的VPD 

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

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

Select * from sales_list ;

當Oracle 在執行該語句時,如果發現 sales_list 表上存在FGAC 政策,于是就會根據 FGAC 政策,按照如下方式改寫該SQL 語句:

Select * from sales_list where seller_id='S0020';

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

Select * from sales_list where values>1000 ;

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

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

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

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

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

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

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

我們也可以創建自己的應用程序上下文,如下所示:

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

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

SQL> drop context sales _ctx;

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

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

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

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

我們創建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;

把執行oe.sales_app_pkg 程序包的權限賦給所有用戶以后,我們可以測試應用程序上下文是否生效了。

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

可以看到,應用程序上下文生效了。接下來,我們創建用于FGAC 規則的函數。

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 /

在這里,我們主要關注 where_condition 函數,該函數會為 FGAC 規則返回限定條件。這種 FGAC 規則函數必須具有兩個傳入參數,第一個參數表示 schema 名稱,第二個參數表示表的名稱。表示對哪 個schema 下的哪個表添加FGAC 規則。同時必須返回字符型的值,該返回值會被Oracle 自動添加到 SQL 語句中的where條件部分。不過函數名稱和參數名稱可以按照需要進行指定。從這里定義的函數 體中可以看出,如果登錄的用戶名以S 開頭,則會受到FGAC 規則的限制,where 條件里會添加 seller_id='Sxxxx' ,Sxxxx 表示登錄的用戶名。否則,如果以其他用戶的身份登錄,則不會受到FGAC規則的限制。

創建了用于FGAC 規則的函數以后,我們開始定義FGAC 規則。

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 程序包來創建 FGAC 規則。我們為用戶 OE下的sales_list 表創建了 規則;該規則利用用戶 OE下的sales_app_pkg.where_condition 函數返回 where條件;該規則作用的 SQL 語句類型為select 和update ;update_check 參數說明是否對更新以后的結果判斷是否滿足 FGAC 規則; 在創建規則的同時,我們也啟用該規則(enable 設置為true )。

創建了FGAC 規則以后,我們需要在用戶登錄到應用程序的時候,調用 sales_app_pkg  程序包里 的set_sales_context 存儲過程來設置該用戶的應用程序上下文里的 seller_id 屬性的值。在實際應用中, 我們可以在登錄界面上,當用戶單擊登錄按鈕的時候進行設置。在這里為了演示效果,我們創建一個 登錄觸發器來設置,如下所示:

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 /

現在,我們可以開始測試FGAC 規則的效果了。

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的身份登錄以后,可以看到,三個銷售人員各自的數據行數。然后以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

很明顯看到,我們設置的FGAC 規則生效了。我們繼續測試更新操作:

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

由于我們在創建FGAC 規則時,指定了update_check 為true ,當用戶 S0010 登錄以后更新sales_list 表,將 seller_id 從S0010 更新為S0020 時報錯,因為 S0010 無權查詢和修改不屬于他的銷售數據。如 果指定update_check 為false ,則允許這樣的update 語句成功。

FGAC 規則的使用是非常靈活的,其關鍵就在于 where_condition 函數的寫法。如果要刪除 FGAC規則,則執行下面的代碼:

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 

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

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

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 /

這里,我們創建了一個規則函數。與 FGAC 規則一樣,該函數必須有兩個傳入參數,第一個表示 要限定的表所屬的schema 名稱,第二個表示要限定的表的名稱。在該函數中,我們定義,如果登錄用 戶為表的屬主,則可以查看所有列;否則,登錄用戶不是表所屬的用戶,則不能查看指定列。

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

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 /

創建基于列VPD 與創建FGAC 政策一樣,也是使用dbms_rls 程序包里的add_policy 存儲過程。 在這里,我們定義了一個名為 hr_emp_col_policy 的政策。該政策作用在用戶 HR下的employees 表上; 采用的政策函數為用戶HR下的hr_col_vpd 。
與FGAC 政策不同的是,我們需要指定另外兩個參數:sec_relevant_cols表示要屏蔽的列的名稱, 可以指定多個列,列與列之間用逗號隔開;sec_relevant_cols_opt 設置為all_rows,則說明對 employees 表里所有的記錄都屏蔽salary 列。

我們以用戶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 列都顯示出來了。然后以用戶OE的身份登錄,執行下面的SQL 語句:

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 列已經被屏蔽了。

感謝各位的閱讀!關于“oracle虛擬專用數據庫的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潢川县| 福泉市| 大埔县| 萝北县| 海安县| 平乐县| 阳泉市| 阳城县| 清新县| 柏乡县| 云安县| 来宾市| 庄河市| 富顺县| 沧源| 时尚| 绥滨县| 江永县| 厦门市| 成武县| 永修县| 金湖县| 兰坪| 乐山市| 天全县| 普定县| 凤翔县| 乐至县| 大埔县| 天津市| 和田市| 永新县| 阿勒泰市| 城口县| 虎林市| 久治县| 德清县| 祥云县| 长治县| 叙永县| 察隅县|