開始之前
簡介
可信上下文建立 DB2 與外部實體(例如 Web 服務器、應用服務器或其他 DB2 服務器)之間的信任關系。在連接時,DB2 檢查連接是否與數據庫中可信上下文對象相匹配。如果匹配,則認為數據庫連接是可信的。通過使用可信上下文,可以在使用受限制的、敏感的特權時提供更強的控制,並且使中間層服務器或應用程序可以向數據庫服務器確定用戶的身份。
關於本教程
本教程帶您經歷一系列的練習,以熟悉 DB2 9.5 中的一個新特性:可信上下文。
本教程是本系列 第 1 部分 的延續,第 1 部分討論了 DB2 角色的概念和特性。該教程演示了如何利用這個新的 DB2 特性,以及如何結合一些重要的電子商務技術(例如 Web 服務、Web 應用服務器和 DB2 數據庫服務器)來使用角色。
目標
本教程幫助您熟悉 DB2 9.5 中可信上下文的概念和特性。在這些練習中,學習:
可信上下文的基本概念
如何創建和管理可信上下文
如何在示例程序中使用可信上下文
基本問題診斷
先決條件
本教程面向的讀者是具有初級到中級技能和經驗的 DB2 專家。您應該對使用 DB2 命令行、CLI 編程和數據庫管理方面的實用知識比較熟悉。
系統需求
要運行本教程中的例子,需要:
DB2 9.5 Express-C
Microsoft Windows 2003、XP 或 Linux(Validated Environment)
Java® Runtime Environment 1.4.2 或更高版本
此外,還應確保硬件滿足 DB2 9.5 的需求。
DB2 9.5 Express C 可通過以上鏈接獲得。DB2 9.5 是一個完整的安裝程序,而不是一個升級補丁包。默認情況下,除非明確要求不自動啟動,否則 DB2 將在安裝後自動啟動。
請使用本教程附帶的 zip 文件中提供的示例腳本和數據來演示本教程中的概念。將 zip 文件解壓到一個名為 DB2TC 的子目錄中(C:\DB2TC 或 home/userid/DB2TC)。本教程通篇將該目錄簡稱為 DB2TC。本教程假設您將 DB2 安裝到默認目錄中。本教程要求創建很多用戶 id,所有練習將使用這些創建的 id。
可信上下文的定義
可信上下文引入了上下文敏感的特權的概念。上下文敏感的特權使公司可以更好地控制一個特權何時可以為一個用戶所用。例如,公司可能希望一個經理只有在從公司辦公室連接到數據庫時才能訪問薪資表,而從家裡連接到數據庫時就不行。
通常情況下,與數據庫服務器的所有交互都通過一個數據庫連接進行,這種數據庫連接是由中間層使用一個用戶 id 和一個憑證的組合建立的,這種憑證向數據庫服務器表明中間層的身份。換句話說,對於數據庫訪問(包括中間層代表用戶執行的那些訪問)所需的所有授權檢查和審計,數據庫服務器使用與中間層用戶 id 相關聯的數據庫特權。
圖 1 說明了這種三層應用程序模型。雖然三層應用程序模型有很多優點,但是在中間層的授權 ID 下進行與數據庫服務器的所有交互(例如用戶請求)會導致一些安全問題。
圖 1. 三層應用程序模型
DB2 可信上下文功能是專門為解決這類安全問題而設計的。可信上下文可以提高安全性,因為它使用實際用戶的身份和數據庫特權來執行數據庫活動。可信上下文還可以提高性能,因為切換用戶時不需要建立新連接。如果切換的用戶的確需要認證,數據庫服務器上也不存在認證新用戶的開銷。
在 DB2 可信上下文中,信任關系基於以下一組屬性:
系統授權 ID:這是表示建立數據庫連接的用戶的授權 ID。
IP 地址(或域名):表示建立數據庫連接時所在的 IP 地址。
數據流加密:用於加密數據庫服務器與連接用戶之間的數據通信的加密級別。
當建立一個數據庫連接時,DB2 將那個連接的屬性與數據庫中每個可信上下文對象的定義相比較。如果連接屬性與一個可信上下文對象的定義相匹配,則那個連接被稱作可信連接。可信連接允許連接發起人獲得那個可信連接之外、沒有提供給他們的附加能力。
構建環境
本教程使用 第 1 部分 “理解 DB2 9.5 中的角色”(developerWorks,2007 年 10 月)中構建的框架。如果您已經完成了第 1 部分,那麼請直接進入 “管理可信上下文” 小節。否則,您需要使用以下說明構建基本環境。
本節介紹一些示例代碼(這些代碼可從本教程下載),以描述角色的行為。這些示例代碼是基於那些可添加到 SAMPLE 數據庫中的數據庫對象的。本節使用的所有腳本都位於子目錄 Section2 中。
要在 DB2 命令窗口中運行腳本,使用:
db2 –tvf scriptname.sql
說明
首先,使用 administrator/root 用戶 id 登錄到系統,然後創建以下用戶 id:
用於 SECADM 的 DB2SEC
將用於管理小組的 MARK、ALLY 和 SAUL
ADAM、DEBS、PETE、YANG、MARY 和 ANNE
ROSE、STAN、ALAN、LORI、EVAN 和 KLEM
這些用戶 id 不需要任何特殊的權限,因為它們將只用於 DB2 數據庫。所有需要的特權和權限將使用 SQL 發出。另外還需要一個名為 Pension_gp 的組。將 ROSE 放進這個組。除此之外不需要設置其他的組權限。如果使用 Windows,那麼應確保用戶不在 Administrators 組中。
下面的圖展示了練習中將用到的公司和角色的層次結構:
圖 2. 角色結構
注意,有些名稱出現在兩個框中,這是因為有些人身兼兩個部門的工作,因此需要處於不止一個角色中。KLEM 是一個新員工,因此沒有被分配到任何角色。
在後面的練習中,DB2 數據庫管理員為 DB2inst1,數據庫為 SAMPLE 數據庫。所有腳本都使用用戶 id DB2inst1 和密碼 “passWord”。如果您使用不同的數據庫或數據庫管理 id(DBA),那麼必須編輯這些腳本,使之與您自己的系統相符。注意確認 “Sample” 或其他可使用的數據庫已經存在。如果不存在,請使用 DB2SAMPL 命令創建 SAMPLE 數據庫,因為本教程後面一直要用到它。
現在,為了進行這組練習,將新用戶和表添加到該數據庫中:
將用戶添加到數據庫中。
以 DBA 身份連接到數據庫,並授予以下特權:
清單 1. 將特權授給數據庫用戶GRANT CONNECT ON DATABASE TO USER MARK;
GRANT CONNECT ON DATABASE TO USER ALLY;
GRANT CONNECT ON DATABASE TO USER ADAM;
GRANT CONNECT ON DATABASE TO USER DEBS;
GRANT CONNECT ON DATABASE TO USER PETE;
GRANT CONNECT ON DATABASE TO USER YANG;
GRANT CONNECT ON DATABASE TO USER SAUL;
GRANT CONNECT ON DATABASE TO USER MARY;
GRANT CONNECT ON DATABASE TO USER ANNE;
GRANT CONNECT ON DATABASE TO USER ROSE;
GRANT CONNECT ON DATABASE TO USER STAN;
GRANT CONNECT ON DATABASE TO USER ALAN;
GRANT CONNECT ON DATABASE TO USER LORI;
GRANT CONNECT ON DATABASE TO USER EVAN;
GRANT SECADM ON DATABASE TO USER DB2SEC;
或者使用 AddUsers.sql 腳本添加這些新用戶。
使用 luwebase.sql 腳本為 SAMPLE 數據庫創建新表。這裡假設將表放在 USERSPACE1 中。
下面添加基本表:
清單 2. 添加基本表LE_DEPARTMENT
LE_EMPLOYEE
LE_EMP_PHOTO
LE_EMP_RESUME
LE_ORG
LE_SALES
LE_PENSIONS
使用 luweload.sql 腳本將數據裝載到新表中。如果使用 Linux,或者改動了裝載文件的位置,那麼必須編輯該腳本。
接著,運行 luweplus.sql 腳本,以創建其他的視圖、索引等數據庫對象。
使用以下命令創建基本角色:
清單 3. 創建基本角色CREATE ROLE Sales;
CREATE ROLE Mktg;
CREATE ROLE Admin;
CREATE ROLE Payroll;
CREATE ROLE Pension;
CREATE ROLE SalesMgr;
CREATE ROLE AdminMgr;
CREATE ROLE CEO;
或者使用 CreateRoles.sql 腳本創建角色。
使用以下命令將特權授給角色:
清單 4. 將特權授給角色GRANT SELECT ON TABLE db2inst1.le_org TO ROLE Sales;
GRANT SELECT, UPDATE, INSERT ON TABLE db2inst1.le_sales TO ROLE Sales;
GRANT SELECT ON TABLE db2inst1.le_org TO ROLE Mktg;
GRANT SELECT ON TABLE db2inst1.le_sales TO ROLE Mktg;
GRANT SELECT ON TABLE db2inst1.le_department TO ROLE Admin;
GRANT SELECT ON TABLE db2inst1.le_employee TO ROLE Admin;
GRANT SELECT ON TABLE db2inst1.le_org TO ROLE Admin;
GRANT SELECT ON TABLE db2inst1.le_sales TO ROLE Admin;
GRANT UPDATE ON TABLE db2inst1.le_department TO ROLE Admin;
GRANT UPDATE ON TABLE db2inst1.le_employee TO ROLE Admin;
GRANT SELECT ON TABLE db2inst1.le_department TO ROLE Payroll;
GRANT SELECT ON TABLE db2inst1.le_emp_photo TO ROLE Payroll;
GRANT SELECT ON TABLE db2inst1.le_emp_resume TO ROLE Payroll;
GRANT SELECT ON TABLE db2inst1.le_pensions TO ROLE Payroll;
GRANT UPDATE, INSERT, DELETE ON TABLE db2inst1.le_employee TO ROLE Payroll;
GRANT SELECT, UPDATE, INSERT, DELETE, ALTER ON TABLE
db2inst1.le_pensions TO ROLE Pension;
或者使用 AssignRoles.sql 腳本創建角色。
現在需要將個人放到他們各自的角色中。使用以下命令授予角色的成員資格:
清單 5. 授予角色的成員資格GRANT ROLE SalesMgr, AdminMgr to ROLE CEO;
GRANT ROLE CEO TO USER Mark;
GRANT ROLE Admin, Payroll to ROLE AdminMgr;
GRANT ROLE AdminMgr TO USER Ally;
GRANT ROLE Sales, Mktg to ROLE SalesMgr;
GRANT ROLE SalesMgr TO USER Saul;
GRANT ROLE Admin TO USER Adam, Debs, Mary;
GRANT ROLE Mktg TO USER Mary, Anne, Rose;
GRANT ROLE Payroll TO USER Adam, Pete, Yang;
GRANT ROLE Pension TO USER Yang;
GRANT ROLE Sales TO USER Stan, Alan, Lori, Evan;
或者使用 AssignUsers.sql 腳本授予角色的成員資格。
在運行該 SQL 腳本時,注意檢查錯誤和警告。可能還需要使用 Control Center 或其他工具查看這些對象,以確認這些表和數據已經存在。
管理可信上下文
可信上下文的使用
注意,對於一個授權 id 只能指定一個可信上下文,可信上下文在本地數據庫上無效。
在 DB2 9.5 中,可以在數據庫中創建一個可信上下文,以定義數據庫與中間層應用服務器之間的信任關系。然後,中間層應用服務器可以建立到數據庫的顯式可信連接,這使中間層應用程序可以將連接上的當前用戶 id 切換到不同的用戶 id,在此過程中可以進行認證,也可以不進行認證。
可信上下文提供了一種機制,通過這種機制,實際的用戶身份和數據庫特權可用於由中間層應用程序代表用戶執行的數據庫請求。此外,通過可信上下文還可以控制數據庫用戶何時可以使用某種特權。
這裡假設所有腳本和程序都位於 DB2TC 目錄中。如果您更改過目錄名稱,那麼可能需要編輯一下腳本。
設置遠程數據庫
要模擬一個遠程數據庫,可以使用還回(loopback),並將本地數據庫定義為遠程。有一種方法可以完成這一任務,其步驟如下:
啟動 DB2 Control Center。
右鍵單擊 All Databases,選擇 Add...。
輸入 127.0.0.1 作為 hostname,選擇 Search 按鈕。
選擇 SAMPLE 數據庫,輸入 SAMPLER 作為 DB alias,單擊 OK。
右鍵單擊數據庫 SAMPLER,選擇 Connect。
當提示測試連接時,輸入您選擇的用戶 id 和密碼。
建議您編輯 Hosts 文件,以便為這些測試創建必要的條目:
可信上下文通信協議
注意,可信上下文惟一支持的協議是 TCP/IP。地址可以以 IPv4、IPv6 或 DNS 格式指定。建議使用 DNS 格式,以避免將地址硬編碼至數據庫中。
127.0.0.1 localhost
192.168.73.134 host1.Admin.LUWent.com
其中 host1 的 IP 地址 是計算機的物理 IP 地址。
下面探索一下可信上下文的創建、修改和刪除:
使用 SECADM userid 連接到數據庫。(如果使用第 1 部分中使用的用戶 id,那麼這個用戶 id 為 DB2SEC)。然後嘗試創建第一個可信上下文:
清單 6. 創建第一個可信上下文CREATE TRUSTED CONTEXT MktgTrustedContext
BASED UPON CONNECTION USING SYSTEM AUTHID Ally
ATTRIBUTES (
ADDRESS 'qwerty',
ENCRYPTION 'HIGH')
DEFAULT ROLE Mktg
ENABLE;
或者使用 MktgTCFail.sql 腳本。該腳本應該會失敗,並返回 DB21034E,因為指定的地址不能通過驗證。
清單 7. 第一個可信上下文失敗CREATE TRUSTED CONTEXT MktgTrustedContext BASED UPON CONNECTION USING SYSTEM
AUTHID Ally ATTRIBUTES ( ADDRESS 'qwerty', ENCRYPTION 'HIGH') DEFAULT ROLE Mktg
ENABLE
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0644N Invalid value specifIEd for keyWord "ADDRESS" in statement "TRUSTED
CONTEXT". SQLSTATE=42615
使用 SECADM 用戶 id 連接到數據庫,然後嘗試創建您的第一個成功的可信上下文。這一次,提供一個有效的地址:
清單 8. 創建有效的可信上下文CREATE TRUSTED CONTEXT MktgTrustedContext
BASED UPON CONNECTION USING SYSTEM AUTHID Ally
ATTRIBUTES (
ADDRESS 'localhost',
ENCRYPTION 'HIGH')
DEFAULT ROLE Mktg
ENABLE;
或者使用 MktgTC.sql 腳本。這個腳本應該可以成功。
清單 9. 成功創建可信上下文CREATE TRUSTED CONTEXT MktgTrustedContext BASED UPON CONNECTION USING SYSTEM
AUTHID Ally ATTRIBUTES ( ADDRESS '127.0.0.1', ENCRYPTION 'HIGH') DEFAULT ROLE
Mktg ENABLE
DB20000I The SQL command completed successfully.
使用 SECADM userid 連接到數據庫,然後嘗試為 Ally 創建第二個可信上下文。這一次將失敗,因為每個用戶只能有一個可信上下文:
清單 10. 為 Ally 創建第二個可信上下文CREATE TRUSTED CONTEXT DupTrustedContext
BASED UPON CONNECTION USING SYSTEM AUTHID Ally
ATTRIBUTES (
ADDRESS 'localhost',
ENCRYPTION 'HIGH')
DEFAULT ROLE Mktg
ENABLE;
或者使用 DupTC.sql 腳本。該腳本應該不能成功。
清單 11. 為 Ally 創建第二個可信上下文失敗CREATE TRUSTED CONTEXT DupTrustedContext BASED UPON CONNECTION USING SYSTEM
AUTHID Ally ATTRIBUTES ( ADDRESS '127.0.0.1', ENCRYPTION 'HIGH') DEFAULT ROLE
Mktg ENABLE
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL20372N The trusted context "DUPTRUSTEDCONTEXT" specifIEd authorization ID
"ALLY " which is already specifIEd for another trusted context.
SQLSTATE=428GL
現在,修改已有的用於 Ally 的可信上下文,以允許她將 id 切換為 Stan,而不必進行認證。使用 SECADM 用戶 id 連接到數據庫,然後修改 MktgTrustedContext,以添加 Stan 的使用。ALTER TRUSTED CONTEXT MktgTrustedContext
ADD USE FOR Stan WITHOUT AUTHENTICATION;
或者使用 AltTC.sql 腳本。該腳本應該會成功。
清單 12. 腳本成功運行ALTER TRUSTED CONTEXT MktgTrustedContext
ADD USE FOR Stan WITHOUT AUTHENTICATION
DB20000I The SQL command completed successfully.
有時候,您可能想禁用某個可信上下文,以臨時阻止對它的使用。使用 SECADM userid 連接到數據庫,然後修改 MktgTrustedContext,禁用該可信上下文。ALTER TRUSTED CONTEXT MktgTrustedContext
ALTER DISABLE;
或者使用 AltTC.sql 腳本。該腳本應該會成功。ALTER TRUSTED CONTEXT MktgTrustedContext ALTER DISABLE
DB20000I The SQL command completed successfully.
最後,和任何其他數據庫對象一樣,可信上下文也可以被刪除。使用 SECADM 用戶 id 連接到數據庫,然後刪除 MktgTrustedContext。DROP TRUSTED CONTEXT MktgTrustedContext;
或者使用 DropTC.sql 腳本。該腳本應該會成功。DROP TRUSTED CONTEXT MktgTrustedContext
DB20000I The SQL command completed successfully.
可信連接中用戶 id 的切換
可信上下文的使用
注意,只有通過 DB2 CLI 應用程序或 DB2 JDBC 應用程序才可以進行這樣的切換。
DB2 允許在不同的授權 ID 下使用建立的可信上下文。為此,定義可信上下文時必須使用特定的 ID。如果指定 PUBLIC,那麼任何授權 ID 都可以使用這個可信上下文。當建立一個顯式可信上下文時,這個可信上下文的創建者就獲得了將連接上的授權 ID 切換到不同授權 ID 的能力。
可信上下文切換用戶
切換必須在事務邊界上進行,否則任何打開的事務將被回滾,連接將中止並返回一個錯誤。
使用提示
一種好的實踐是使用一條顯式的 COMMIT WORK 語句完成工作或事務的所有邏輯單元。這樣就建立了一個事務邊界,可以確保在切換 ID 之前正在處理的所有工作都能完成。
對於每個可信上下文對象,安全管理員可以選擇指定允許切換到的 ID 列表,並且可以指定進行切換時是否需要驗證。安全管理員還可以為各個 ID 指定默認角色或備選角色。
下面探索如何使用可信上下文以及切換用戶的功能:
在為 Ally 創建可信上下文之前,使用 Ally 連接到 SAMPLER 數據庫,並嘗試更新 LE_PENSIONS 表:UPDATE DB2INST1.LE_PENSIONS SET BASE=BASE + 2500 WHERE EMPNO='012214'
或者使用 UPDtab.sql 腳本。該腳本應該會失敗,因為 Ally 沒有執行這項操作的特權。
清單 13. 腳本失敗DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0551N "ALLY" does not have the privilege to perform Operation "UPDATE" on
object "DB2INST1.LE_PENSIONS". SQLSTATE=42501