今天又接到使用者來咨詢怎麼對同一要素類對不同要素設定權限的問題,看來這個需求大家都是非常迫切。
重新解釋一下使用者的要求,比如說我有一個整個北京市宗地的要素類,所有地區的要素類都在一起,但是有一個要求,使用者隻想在一個要素類裡面進行操作,而且朝陽區國土局的從業人員隻能編輯所屬朝陽區的資料,海澱區國土局從業人員隻能編輯所屬海澱區的宗地,其實也就是一個同一要素類對不同要素設定權限的問題。
之是以有這個需求,大家都是所有資料在同一個要素類,而不是分區域要素類,那麼對一個要素類的不同要素權限就顯得需求迫切了。
在以前我也寫過類似的文章,但是那些方法還是有不足之處,不是特别符合要求:http://blog.csdn.net/linghe301/article/details/7053965
今天在Esri中國論壇看到了一個文章,啟發很大,借助于他的建議,自己做了相關實驗,還是可以滿足相關需求的。
這裡感謝@GAT5的分享精神:http://bbs.esrichina-bj.cn/ESRI/viewthread.php?tid=125974&page=1&extra=#pid1067570
他的文章細節寫的不多,下面我就對我的這次測試,以及在測試中遇到的問題跟大家做分享。
預前知識:VPD 概述
虛拟專用資料庫(Virtual Private Database,VPD)将伺服器實施的細粒度通路控制和安全應用程式上下文結合起來。支援上下文的函數傳回一個謂詞,即where子句,該子句自動附加到所有的select語句或其他DML語句。換句話說,由VPD控制的表、視圖、同義詞上的select語句将根據where子句傳回行的子集,該子句由通過應用程式上下文生效的安全政策函數自動生成。VPD的主要組成部分是行級别的安全性(RLS),也稱為"細粒度的通路控制"(FGAC)。
因為VPD在語句解析期間透明地生成謂詞,是以無論使用者是否正在運作特别的查詢、檢索應用程式中的資料或者檢視Oracle Forms中的資料,都可以一緻地實施安全政策。因為Oracle Server在解析時将謂詞應用于語句,是以應用程式不需要使用特殊的表、視圖等來實作該政策。是以,Oracle可以使用索引、物化視圖和并行操作來優化查詢,而以其他的方式則不能夠進行優化。是以,相比于使用應用程式或其他方式過濾結果的查詢,使用VPD可能會産生較少的系統開銷。
從維護的角度來看,安全政策可以在安全函數中定義,使用角色和權限很難建立這種安全函數。類似地,應用程式伺服器提供商(Application Server Provider,ASP)可能隻需要建立一個資料庫來為相同應用程式的多個客戶服務,使用VPD政策來確定一個顧客的雇員隻可以檢視他們自己的資料。DBA可以使用少量的VPD政策維護一個較大的資料庫,而不是針對每個客戶都使用一個單獨的資料庫。
Oracle 10g中的新增内容是列級别的VPD操作。使用列級别的VPD,DBA可以限制對表中特定列的通路。查詢傳回相同數量的行,但如果使用者的上下文不允許通路列,則在限制的列中傳回NULL值。
虛拟專用資料庫如何工作
将一個或多個安全政策與表或視圖關聯後,就可以實作虛拟專用資料庫。對帶安全政策的表進行直接或間接通路時,資料庫将調用一個實施該政策的函數。政策函數傳回一個通路條件(WHERE 子句),即謂詞。應用程式将它附加到使用者的 SQL 語句,進而動态修改使用者的資料通路權限。
你可以通過編寫一個存儲過程将 SQL 謂詞附加到每個 SQL 語句(用于控制該語句的行級别通路權限)來實施 VPD。例如,如果 John Doe(他屬于 Department 10)輸入 SELECT * FROM emp 語句,則可以使用 VPD 添加 WHERE DEPT = 10 子句。這樣,您便可以通過對查詢進行修改來限制通路某些行的資料。
虛拟專用資料庫確定無論使用者以何種方式通路資料(通過應用程式、報表編寫工具或 SQL*Plus),都将強制實施同一強大的通路權限控制政策。這樣,使用 VPD ,銀行便可以確定客戶隻看到他們自己的帳戶,電信公司可以安全地隔離客戶記錄,人力資源應用程式可以支援複雜的員工記錄資料通路原則。
其實總結起來一句話,我們可以設定完畢之後,查詢或者編輯過程中自動添加一個WHERE條件。
實驗資料:
使用者:SDE,我在SDE使用者建立一個要素類test123,裡面有一個X字段(整型)
SQL> desc sde.test123
名稱 是否為空? 類型
----------------------------------------- -------- ----------------------------
OBJECTID NOT NULL NUMBER(38)
QUXIAN NVARCHAR2(50)
SHAPE ST_GEOMETRY
X NUMBER(5)
使用者:DDD,普通使用者
-- Create the user
create user DDD
identified by ""
default tablespace SDE
temporary tablespace TEMP
profile DEFAULT
password expire;
-- Grant/Revoke object privileges
grant select, insert, update, delete on A69 to DDD;
grant select, insert, update, delete on D69 to DDD;
grant select, insert, update, delete on TEST123 to DDD;
grant select, insert, update, delete on TEST123_VW to DDD;
-- Grant/Revoke role privileges
grant connect to DDD;
grant resource to DDD;
-- Grant/Revoke system privileges
grant unlimited tablespace to DDD;
我使用ArcGIS的權限功能,将SDE使用者的test123要素類給DDD賦予SELECT、INSERT、UPDATE、DELETE權限。
那麼我使用DDD使用者就可以看到sde使用者下的test123的所有資料。
那麼我的需求就是,我隻想讓DDD使用者看到test123要素類中X=2的要素。
VPD包含兩個要素:政策(policy),政策函數(policy Function)
編寫政策函數(fn_reg)
CREATE OR REPLACE FUNCTION fn_reg (p_owner in varchar2, p_object in varchar2) return varchar2 IS
v_region varchar2(20);
begin
v_region := sys_context('USERENV','SESSION_USER');--獲得登入使用者
if v_region = 'DDD' then ---如果登入使用者是DDD
return 'X=2'; ---相關WHERE條件就是X=2
else
return null;
end if;
end fn_reg;
如果使用者比較多,可以将這個使用者放在一個表中,或者參考上面的連結,好像編寫政策函數不支援else if
一般情況下通過完善政策函數來對使用者的業務進行定義
政策(policy)使用者管理(添加、删除、修改)對那些對象(表或視圖)執行RLS(行級安全)控制。
添加政策
begin
dbms_rls.add_policy(object_schema => 'sde',object_name => 'test123',policy_name => 'pol',function_schema => 'sde',policy_function => 'fn_reg',Statement_Types =>'Select,Insert,Update,Delete,Index',Enable =>True);
end;
/
begin
dbms_rls.add_policy(object_schema => 'sde',object_name => 'a69',policy_name => 'pol_a',function_schema => 'sde',policy_function => 'fn_reg',Statement_Types =>'Select,Insert,Update,Delete,Index',Enable =>True);
end;
/
dbms_rls.add_policy(
object_schema => 'sde', ——使用者
object_name => 'test123',——對test123要素類
policy_name => 'pol',——政策名稱
function_schema => 'sde',——政策函數所屬使用者
policy_function => 'fn_reg',——上面編寫的政策函數
Statement_Types =>'Select,Insert,Update,Delete,Index',——相關權限
Enable =>True); ——是否啟動政策
添加政策的相關屬性
參 數 | 說 明 |
object_schema | 包含由政策保護的表、視圖或同義詞的模式。如果該值是NULL,則使用調用過程的使用者的模式 |
object_name | 由政策保護的表、視圖或同義詞的名稱 |
policy_name | 添加到該對象的政策的名稱。對于受保護的每個對象,該政策名必須唯一 |
function_schema | 擁有政策函數的模式;如果該值為NULL,則使用調用過程的使用者的模式 |
policy_function | 函數名稱,該函數為針對object_name的政策生成謂詞。如果函數是程式包的一部分,則在此處必須也指定程式包名,用于限定政策函數名 |
statement_types | 應用政策的語句類型。允許的值(以逗号分隔)可以是SELECT、INSERT、UPDATE、DELETE和INDEX的任意組合。預設情況下,除了INDEX之外的所有類型都适用 |
update_check | 對于INSERT或UPDATE類型,該參數是可選項,它預設為FALSE。如果該參數為TRUE,則在檢查SELECT或DELETE操作時,則對INSERT或UPDATE語句也要檢查該政策 |
enable | 該參數預設為TRUE,表明添加該政策時是否啟用它 |
Static_policy | 如果該參數為TRUE,該政策為任何通路該對象的人産生相同的謂詞字元串,除了SYS使用者或具有EXEMPT ACCESS POLICY權限的任何使用者。該參數的預設值為FALSE |
policy_type | 如果該值不是NULL,則覆寫static_policy。可允許的值是STATIC、SHARED_STATIC、CONTEXT_SENSITIVE、SHARED_CONTEXT_SENSITIVE和DYNAMIC |
Long_predicate | 該參數預設為FALSE。如果它為TRUE,謂詞字元串最多可為32K位元組長。否則,限制為4000位元組 |
sec_relevant_cols | 實施列級别的VPD,這是Oracle 10g的新增内容。隻應用于表和視圖。在清單中指定受保護的列,使用逗号或空格作為分隔符。該政策隻應用于指定的敏感列位于查詢或DML語句中時。預設情況下,所有的列都是受保護的 |
sec_relevant_cols_opt | 允許在列級别VPD過濾查詢中的行仍然出現在結果集中,敏感列傳回NULL值。該參數的預設值為NULL;如果不是預設值,則必須指定DBMS_RLS.ALL_ROWS,用于顯示敏感列為NULL的所有列 |
注意:上面為什麼還有對a69表進行添加政策,如果使用者将test123注冊版本了,那麼會産生相關的A表。
删除政策
BEGIN
DBMS_RLS.drop_policy (object_schema => 'SDE',
object_name => 'test123',
policy_name => 'POL');
END;
/
添加之後,我們需要檢視一下是否有效 1:可以使用PL/SQL進入sde使用者下檢視Function的fn_reg是否編譯正确 2:檢視V$VPD_POLICY特别注意PREDICATE是有相關的條件資訊比如X=2
SQL> select object_owner,object_name,policy,predicate from V$VPD_POLICY;
OBJECT_OWNER OBJECT_NAME POLICY PREDICATE
------------------------------ ------------------------------ ------------------------------ -------------------------------------------------------------
SDE TEST123 POL
SDE TEST123 POL X=2
SDE TEST123 POL X=2
SDE T POLICY_LIMITED_QUERY_T X <= 10000
SDE TEST123 POL
SDE A69 POL_A X=2
SDE A69 POL_A X=2
那麼進行測試,我使用sde使用者登入之後

那麼我使用ddd使用者登入之後
我們可以使用ddd使用者隻過濾x=2的要素。 那麼我們在ArcMap上連接配接ddd使用者對test123進行編輯,一開始老報ORA-28115: 政策違反檢驗選項。 倒騰半天,忽然開竅,我設定的政策是過濾X=2,那麼我建立要素并沒有設定X=2,是以報ora-28115錯誤。 剛好,我可以使用ddd使用者連接配接,設定一個編輯模闆,這個編輯模闆設定x=2即可。
通過上面的測試,我們就可以模拟,在同一個要素類對不同的要素進行權限的設定,而且可以進行相關的讀和寫的操作。
也就是可以實作: 一個要素類包含北京市的所有資料,那麼海澱區使用者隻能看到而且隻能編輯海澱區的資料,朝陽區使用者隻能看到而且隻能編輯朝陽區的資料,北京市局的使用者可以檢視和編輯所有區的資料。
而且即便是使用者通過SQLPLUS的方法檢視表也是隻能檢視自己區域的資料,安全性也得到了保證。
由于上面使用的都是純Oracle知識,還不确定是否在應用在ArcSDE裡面有沒有相關的Bug或者問題,這個有待大家一塊交流和分享。
-------------------------------------------------------------------------------------------------------
版權所有,文章允許轉載,但必須以連結方式注明源位址,否則追究法律責任!
-------------------------------------------------------------------------------------------------------