星期三, 9月 13, 2006

JDBC 密碼問題

又是很久沒更新 Blog 了~

現在來說說在使用 JDBC Driver 時常常會被要求密碼明文不要直接寫在檔案裡的解決方式...

我們在設定 JDBC Resource 時, 通常都需要將帳號密碼存在設定檔內. 不過有些客戶會因為安全需求強烈要求密碼的部份不應該直接存在設定檔內~

在之前的系統我是採用 proxool connection pool, 此套件會去讀取一個設定檔. 於是我的做法是將讀取設定檔時, 我先parse出裡面的密碼, 然後再轉成真正的密碼給 proxool~

當時的做法是治標不治本~由於很多系統是透過 Container 去管理 data source...
不像之前是寫獨立的系統, 所以根本無法使用上述的方法~
例如 JBoss 上的 ejb 所使用的連線都是 container 去讀取設定檔並管理連線, 若依前述做法, 則要去改 JBoss 的 source code 在讀設定檔時多一層轉換以符合需求. 工程耗大.

想了一下之後, 覺得可以做一個 JDBC Driver Proxy...
處理帳號密碼之後, 將真正的請求連線交給真正的 JDBC Driver...

所以後來的使用方法就像一般的 JDBC 的用法, 而 Driver 與 URL 的地方則會有一些變化..
如下:

  • JDBC Driver: idv.allen.jdbc.Driver
  • JDBC URL: allen:{driver}:{url}
此 Driver 會宣告接受 allen 開頭的 URL, 而我們的 Driver 需要知道所代理的 Driver 與 URL,
所以後面接著這兩個資訊, 其中, {driver} 就是真正的 JDBC Driver, 而 {url} 就是真正的 URL.
設定帳號密碼時, 就用加密過的帳號密碼..
而此 JDBC Driver 會將所傳入的帳號密碼轉回明碼之後, 再交給真的 Driver 去取得連線...

由上面的 URL 樣式可以知道, 並沒有指定要用什麼方式解碼~
其實此 Driver 預設會採用 hex 來還原密碼, 而帳號則不處理...

後來, 我又擴充此 JDBC Driver, 其 URL 樣式如下
  • JDBC URL: allen[.{decrypt}]:{driver}:{url}
其中, [.{decrypt}] 是可有可無的..若沒有的話, 則像上述採用預設的方式~

若我們想用其他的解碼方式..則必須實作 idv.allen.jdbc.decrypt.DecryptIF
其中有兩個方法需要實作:
  • String getUserName(String userName): 若不需解密帳號, 則直接回傳即可.
  • String getPassword(String password): 會將所設定的 password 傳入, 依自己想要的解碼方式解碼後回傳真正的 password.
此實作物件之 Class 為了方便起見, 要放在 idv.allen.jdbc.decrypt 的 package 裡面.
假設我們實作了一個 Class 為 idv.allen.jdbc.decrypt.OctalDecrypt...
若要採用此解碼方式, 則 URL 如下:
  • JDBC URL: allen.OctalDecrypt:{driver}:{url}
這樣此Driver會動態去建構此解碼物件並將轉換事宜交給此 Class 去處理...

這樣一來. 往後不論是什麼系統, 要將 JDBC 設定之帳號密碼設為密文, 都可以透過此自製的 JDBC Driver 解決...且不會影響到原本系統的程式與架構...

以上的概念是從 proxool connection pool 中得到的靈感, 由於 proxool connection pool 也實作了自己的 JDBC Driver, 使得要採用 proxool connection pool 的方式也變得比較簡單..

善用設計模式, 可以很漂亮的解決許多問題 :)

0 Comments:

張貼留言

<< Home