現在保護每一行的安全
|
||
|
作者:Darl Kuhn、Steve Roughton Oracle Label Security(Oracle標籤安全性)按行來控制用戶的訪問。 絕大多數商業應用程序都必須處理安全性問題。應用程序經常需要限制對專用記錄的訪問、建立審計跟蹤,或者執行一個工作流過程,所有這些都要符合公司的安全策略。構建安全的軟件是一個富有挑戰性且複雜的工作,在整個機構內管理軟件的安全策略可能會更困難。 作爲模式(schema)設計人員,你可能會在表中添加安全性列並根據這些表創建用戶特定的視圖。作爲DBA,你可能會創建角色和權限來保護數據庫對象。而作爲開發人員,你可能會編寫PL/SQL包,將安全事務處理封裝在應用程序內。所有這些技術都很有效,但這些方法也都具有一定的缺點。例如,某人可能會無意中將專用數據導出至一個個人模式、原有的應用程序可能與安全對象不兼容,或者用戶可能會利用SQL*Plus繞過整個應用程序的安全性檢查。 Oracle9i數據庫有一個可以幫助解決這些問題的組件:Oracle Label Security。Oracle Label Security最早引入Oracle8i第三版(8.1.7),它是一個使你能夠建立並實施企業安全性策略的簡捷工具。 Oracle Label Security是內置於數據庫引擎中的過程與約束條件集,該數據引擎實施對在單個表或整個模式上的"行"級訪問控制。要利用Oracle Label Security,需要創建一個或多個安全策略,其中每一個安全策略都包含一組標籤。你可以用這些標籤來標明哪些用戶能夠訪問什麼類型數據。在創建了一個策略之後,將該策略應用於需要保護的表,並將這些標籤授予你的用戶,這樣,你就完成了整個過程。Oracle Label Security對查詢的修改是透明的,並且在即時計算訪問級別,以執行你的新策略。 當Oracle9i數據庫在解析各個SQL語句時,它也檢測各個表是否受到某個安全策略的保護。根據該用戶的訪問權限,Oracle9i數據庫向該語句的WHERE子句中添加安全性謂詞。因爲這些都發生在數據庫引擎的內部,所以不管該SQL語句的來源如何,用戶都不可能繞過該安全性機制。 它是如何工作的? 這裏有一個非常簡單的例子,可以說明Oracle Label Security是如何工作的。我們創建了名爲documents的表,並向其中填入了4個記錄,同時定義了兩個安全級別:PUBLLIC(公共)與INTERNAL(內部)。每個級別各有一個數字值:1000或2000。接着可以爲表的每一行指定一個級別。下面給出對該表進行的一個簡單SELECT:
SQL> SELECT * FROM documents; DOCID DOCNAME LEVEL DOC_LABEL
現在假定在我們的數據庫中有兩個用戶:EMP與MGR。我們爲這些用戶指定如下訪問級別: EMP 被指定爲 PUBLIC只讀。 MGR 被指定爲 PUBLIC與INTERNAL 讀/寫。 當這兩個用戶訪問此 documents表時,其內部會發生什麼呢?假定EMP用戶運行下面的查詢:
SELECT * FROM documents;
Oracle9i數據庫對該查詢進行解析,並判定該表是受標籤安全性的保護。Oracle Label Security向該查詢中添加一個 WHERE 子句,以確保該EMP只能看到標記有 PUBLIC 訪問的行:
SELECT * FROM documents
下面是該 EMP 用戶在運行此查詢後所看到的內容:
DOCID DOCNAME LEVEL DOC_LABEL 你可能想知道:"爲什麼不根據某一列值,創建一個限制訪問的視圖呢?"事實上,如果你的應用程序只需要幾個級別,並沒有特殊的安全要求要考慮,那麼向你的表中添加一個安全性列,然後再利用視圖就可以了。 但假設你的系統要求發生了變化,你現在需要利用對改變數據集的定製的讀/寫許可跨多個機構來管理數個級別的用戶。此外,這些機構位於不同的國家,各自都有自己的法律和安全性限制。如果僅使用視圖,就很難滿足這些要求了。 幸運的是,Oracle Label Security就是爲了適應擴展而設計的,因此實施此類應用程序安全性可能比你預計的更容易。 一個練習示例 實施Oracle Label Security包括以下10個步驟: 安裝Oracle Label Security(每個數據庫進行一次) 步驟1;安裝Oracle Label Security 啓動Universal Installer。
SQL> CONN sys/password AS SYSDBA;
注意:此catols.sql腳本在其最後一步對數據庫進行SHUTDOWN IMMEDIATE (立即關閉)。 重新啓動實例並運行
SQL> SELECT username FROM dba_users;
你將看到一個新的包括所有Oracle Label Security對象的 LBACSYS用戶。其缺省口令是LBACSYS (所以一定要更改該口令)。該用戶將管理你的安全策略。 步驟2:創建一個安全性策略 在本例中,你需要定義對公司文檔的行級別的訪問。在此步驟內,創建一個名爲DOC_POLICY的策略。要創建一個策略,先以LBACSYS身份建立連接,然後利用 sa_sysdb.create_policy過程:
SQL> CONN lbacsys/lbacsys
第一個參數DOC_POLICY是該策略的名字,第二個參數DOC_LABEL是一個列的名字,Oracle Label Security將把該列添加到你將在標籤控制下替換的表內。 爲了覈實你的策略已經創建,可按下面方式查詢DBA_SA_POLICIES :
SQL> SELECT policy_name, status POLICY_NAME STATUS
要禁用、重新啓用或者刪除一個策略,可利用以下過程:
SQL> EXEC sa_sysdba.disable_policy
步驟3:定義級別
SQL> EXEC sa_components.create_level
每個級別都有一個策略名、一個數字ID、一個縮寫名與一個全名。該數字ID表示敏感度級別--編號越高,表明敏感度越高。在本例中,INTERNAL 比PUBLIC的敏感度要高。爲了查看你所創建的級別,執行下面過程:
SQL> SELECT * FROM dba_sa_levels
步驟4:定義區間(可選)
SQL> EXEC sa_components.create_compartment sp; ('DOC_POLICY', 100,
區間有一個策略名、一個數字ID、一個縮寫名與一個全名。區間的數字ID並不指定其敏感度的級別。它僅用於在顯示訪問信息時對區間進行排序。要了解關於區間的信息,可以查詢DBA_SA_COMPARTMENTS視圖。 步驟5:定義分組(可選) 在創建一個分組時,必須定義一個層次(hierarchy)。在本例中,ALL_REGIONS是父,WEST_REGION和EAST_REGION是ALL_REGIONS的子。
SQL> EXEC sa_components.create_group
與區間類似,分組也具有一個數字ID、一個縮寫名和一個全名。此外編號(數字)並不表示任何敏感度,它僅用於在顯示分組信息時對其進行排序。要觀察關於分組的信息,可查詢DBA_SA_GROUPS視圖。 步驟6:創建標籤 標籤是級別、區間與分組的縮寫名的一個組合,並遵循以下語法:
級別: 區間, ... 區間_n:分組,.. 分組_n 級別、區間與分組都必須用冒號隔開。如果指定了一個以上的區間或組,它們必須用逗號隔開。 例如,可能有一些財務部門的用戶,他們只能訪問內部文檔。其標籤類似於:
INTERNAL:FIN(內部:財務) 在創建一個標籤時,必須爲其指定一個編號。該編號在數據庫的所有策略中是惟一的。要查看標籤信息,可查詢DBA_SA_LABELS視圖。 步驟7:將標籤策略應用於表
SQL> EXEC sa_policy_admin.apply_table_policy - 在運行此過程時,Oracle9i數據庫向documents表中添加一個名爲DOC_LABEL的列。這個列的名字是在步驟2中創建該安全策略時定義的。如果你描述該documents表,你將看到如下所示的新的DOC_LABEL列:
SQL> DESC app.documents
當你應用該策略時,你也可以通過在TABLE_OPTIONS參數中指定HIDE,取消來自用戶的該列:
table_options&n bsp; => 'LABEL_DEFAULT,READ_CONTROL,WRITE_CONTROL,HIDE'
這個TABLE_OPTIONS參數使你能夠定義將把什麼類型的控制應用到該表上。LABEL_DEFAULT指明,如果沒有爲一個 INSERT語句提供標籤,那麼將使用缺省的會話行標籤。READ_CONTROL參數規定該 SELECT, UPDATE和DELETE訪問在整個標籤內是有效的。WRITE_CONTROL參數決定哪些INSERT, UPDATE活動是通過一個標籤獲得授權的。 要確定哪些策略已經被應用到了哪些表和模式,可以查詢DBA_SA_TABLE_POLICIES視圖。 步驟8:指定用戶標籤 MGR被賦予了最高級別的讀/寫權限。 這些過程將一個用戶映射到訪問級別和被指定了標籤的行。爲了查看用戶及訪問級別,可查詢DBA_SA_USER_LABELS視圖。 步驟9:指定正常授權級別的訪問
SQL> CONN app/app
步驟10:指定合適的標籤
SQL> CONN mgr/mr_bigg
如果表中已經有了數據,那麼你需要用合適的標籤值來更新該標籤列(DOC_LABEL)。因爲該表已經處於Oracle Label Security 控制之下,所以必須用一個具有權限的模式來更新該標籤列。當然,也可以暫時禁用該策略,先更新該標籤列,然後再重新啓用該策略。如果用SQL*Loader向一個受保護的表中插入數據,則先要確保加載的用戶(模式)具有合適的標籤寫入權限。 對一個表啓用了標籤安全性控制後,如果沒有合適的標籤權限,即便是表的所有者也不能讀取或寫入。該規則的一個變體是,表的所有者可以在沒有Oracle Label Security DELETE許可的條件下截短其數據。 操作數據 現在當你以不同的用戶身份連接時,請注意你只能按照你的安全性策略和CRUD訪問所規定的那樣操作數據:
SQL> CONN mgr/mr_bigg
如果以HR_EMP身份連接,則相同的查詢將返回以下內容:
DOCNAME DOC_LABEL
如果以 EMP身份連接,相同的查詢則只返回以下內容:
DOCNAME DOC_LABEL------------- --------- SHARE_WARE 10000
當任一SQL語句訪問該APP.DOCUMENTS表時,Oracle9i數據庫首先驗證CRUD訪問,然後施以Oracle Label Security限制。這樣,用戶只能執行經授權的操作。 DBA應考慮的事項 如果你是一位DBA,那麼還有另外一些需要考慮的事項。當你導出受Label Security保護的數據時,只能使用一個具有所賦予的適當讀取權限的模式導出該數據。例如,如果你想以SYSTEM身份導出APP.DOCUMENTS 表,將會得到以下消息:
EXP-00079: Data in table "DOCUMENTS" is protected.(表"DOCUMENTS"中的數據受到保護) Conventional path may only be exporting partial table.(常規的路徑只能導出部分表) . . exporting table DOCUMENTS 0 rows exported(導出表DOCUMENTS中的0行被導出) 你不能將一個安全性策略應用於該SYSTEM 模式。你將需要利用一個對錶中受標籤保護的所有行有讀取權限的非SYSTEM模式。例如,如果你有一個用來導出你的數據庫的EXPUSER 模式,則你需要授予它對受策略保護的所有行的特殊READ權限:
SQL> EXEC sa_user_admin.set_user_privs 要授予一個模式對受策略保護的數據的完全讀取和寫入權限,則可以利用FULL關鍵詞:
SQL> EXEC sa_user_admin.set_user_privs 注意:任何被授予SYSDBA權限的模式(如SYS)都可以看到所有數據,而不管這些數據是否受Label Security保護。 無論你有什麼特殊權限(如FULL,全權),你都不能利用導出實用程序來備份LBACSYS模式。如果你試圖導出LBACSYS,你將收到一個出錯提示:"LBACSYS is not a valid username.(LBACSYS不是一個有效用戶名)"。因此,你需要利用數據庫的一個物理備份(熱備份、冷備份或RMAN)來備份LBACSYS的對象。 在將受標籤保護的數據導入另一個數據庫之前,需要先安裝Oracle Label Security。還需要預先創建策略和標籤,並確保導入的模式(用戶)具有完全的寫入權限。具體細節,請參見Oracle Label Security管理員指南第12章。 如果有大量受Label Security保護的數據,那麼你就需要一個調優策略。根據標籤基數(cardinality)的不同,你可能希望考慮向標籤列中增加一個B樹索引或一個位映射索引。例如,如果標籤的基數較高,那麼就應當使用一個B樹索引。 Oracle建議對LBACSYS模式的對象以及應用程序表和索引進行分析,以改進由基於成本的優化器所生成的執行計劃。我們建議在對安全性策略進行任何改變後,對LBACSYS對象進行分析。 結論 Oracle9i數據庫中的Oracle Label Security提供了一種對數據進行細粒度訪問控制的安全的方法。這一特性被封裝在數據庫引擎中,所以不可能繞過它,它提供了一種實施和維護複雜"行"級別安全性所需要的安全的方法。 |