5. 安全性考慮
作為網絡上的語言Java必須十分注安全性的考慮。基於上面的討論,JDBC的兩種主要使用場合裡面,我們必須考慮安全性問題:
* 在Java applications的場合裡面Java代碼是本地的,所以也是"trusted"
* 沒有驗證的Java applet代碼不可以存取本地的以及其他網絡的數據。
5. 1. JDBC 和未驗證的applet
JDBC首先必須符合Java的一般安全規則。另外:
* JDBC 必須認為沒有驗證的applets是不可靠的。
* JDBC 不可以讓不可靠的applets存取本地數據庫。
* 一個已經向JDBC DriverManager注冊的是JDBC Driver只能存取它所來的數據源。
* 一個applet也只能向它所Download來的服務器來存取數據。
如果JDBC驅動層如果完全確信對一個數據庫服務器打開連接不會引起認證或者權限問題(可能由網上隨機主機上運行的程序引起),那麼它就允許applet打開這樣的連接。
數據庫服務器不通過IP地址來限制存取是相當少的,主要是為了舉例。(當心,這一段話我可能翻譯反了!!!大家看看原文。)這些限制是相當煩瑣的。不過他們與對一般applet的限制是一致的我們沒有必要放開這些限制。
5. 2. JDBC 和Java應用程序
對於一個普通的Java應用程序(例如全部用Java代碼而不是不可靠的applet )JDBC將從本地的類路徑裡面獲得驅動,並且允許應用程序自由存取文件,遠程服務器等等。
但是和applet一樣,如果由於某些原因一個沒有驗證的sun.sql.Driver類從遠程的來源裡面獲得,那麼這個驅動只能和相同地方來的代碼配合。
5. 3. Driver的安全責任
JDBC driver可能在各種情況下使用,所以驅動的編制者遵循一定的簡單的安全規則,從而避免applet做非法的數據庫連接。
如果所有的驅動都象applet一樣從網上下載,那麼這些原則將是不必要的,因為普通的安全規則已經對它做了限制。
但是驅動的編寫者必須記住一旦他們的驅動獲得成功,用戶將在本地磁盤安裝這些驅動,那麼驅動將成為Java環境中一個被信任的部分,所以必須確信它不會被來訪的applet所濫用。所以我們鼓勵所有的驅動編寫者必須遵循一定安全原則。
所有這些原則都是在連接打開的時候使用。這正式驅動和虛擬機器檢查當前調用者是否真的可以與指定的數據庫連接的時刻。一旦連接建立就不必做更多的檢查了。
5. 3. 1. 分享TCP/IP連接的時候必須謹慎
如果一個JDBC驅動試圖打開一個 TCP 連接,那麼這個打開會被Java 安全管理機制自動檢查。這個機構會檢查當前調用棧裡面有沒有applet,如果有那麼就限定它可以訪問的機器集合。所以一般地JDBC驅動可以把TCP建立檢查留給Java虛擬機。
但是如果一個JDBC驅動試圖在多個數據庫連接之間共享一個TCP連接,那麼驅動就必須自己負責檢查每個調用者是否真的被允許與目標數據庫聯系。
例如如果我們為applet A打開了一個通往機器foobah 的TCP連接,這並不意味著applet B被自動允許來共享這個連接。
applet B可能沒有任何訪問機器foobah的權力。所以在允許某個程序重用一個現成的TCP連接之前,JDBC 驅動必須通過安全機構來檢查當前的的調用者是否可以訪問這個連接。通過下面的代碼可是實現這個功能。
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkConnect(hostName, portNumber);
}
如果連接是不允許的,那麼Security.checkConnect方法將產生一個Java.lang.SecurityException。
5. 3. 2. 檢查所有的本地文件訪問。
如果一個JDBC取得需要訪問本地機器上的數據,那麼他必須確信調用者是被允許打開這個文件的。例如:
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkRead(fileName);
}
如果對特定文件的訪問是不允許的,那麼Security.checkRead方法將產生一個Java.lang.SecurityException。
5. 3. 3. 作好最壞的准備
一些驅動可能使用本地的方法來橋接底層數據庫程序。則這些情況裡面判斷那些本地文件將被底層函數所訪問是困難的。
在這些環境裡面用戶必須作好最壞的打算,並且否決所有下載applet所發出的數據庫存取,除非驅動可能完全確信將要做存取是沒有問題的。
例如一個JDBC-ODBC橋接器必須檢查ODBC數據源的的名稱,確保applet只可以訪問它的"生源地"。如果對有的名字中不能判斷出數據源的主機名,那麼只能否決這個訪問。
為了決定一個當前的調用者是可以信賴的應用還是一個applet,JDBC驅動必須能夠檢查這個調用者是否可以寫一個隨機的文件:
SecurityManager security = System.getSecurityManager();
if (security != null)
{
security.checkWrite("foobaz");
I. }