上次 利用 SSL 讓 PostgreSQL 有一個安全的網路傳輸 談到如何在 PostgreSQL 伺服器端上設定,讓資料通訊能夠以 SSL 加密所要傳送的資料。那篇文章的最後,我留了一個伏筆,不在該篇討論客戶端的連接。那是因為依客戶端的特質的不同,SSL 加密連接的設定方式也就不同,如果要在當時就討論,那麼那篇文章就太過冗長了。PostgreSQL 的客戶端的連接方式很多,如果你用的語言是 C,那麼你可以直接用 libpg 這類的 API 直接連接;用 Java 的,當然得透 JDBC driver (除非你太閒,想證明自己的實力,用 JNI 來寫);如果你用 MS Access,那麼就要用 ODBC 來連接;如果你要用 Visual BASIC.NET、C# 則用 .NET provider......。換句話說,客戶端不同時,SSL 的設定方式就不同。到目前為止,唯一讓我撞牆的只有 OpenOffice 的 SDBC 以及 OLEDB Provider (這部份還要再確認一下) 目前還沒支援 SSL;其它的中介軟體,都可以找到設定的方式。我這篇先從 JDBC 講起。
PostgreSQL JDBC 以 SSL 連接伺服器的方法太簡單了,簡單到用一篇文章來說明似乎太浪費版面,因此,我順便提一下,如何設定 NetBeans,讓 NetBeans 可以很容易的連上 PostgreSQL server。由於 NetBeans 是 Java 的 IDE 開發工具,所以它的資料庫工具,也一定是用 Java 寫成的,所以工具和資料庫的連接界面必定也是用 JDBC。所以,要知道如何讓這個工具以 SSL 加密連接伺服器前,讓我們先看看 JDBC 要如何設定,才能以 SSL 加密連接伺服器。
首先必須先下載 JDBC Driver,PostgreSQL JDBC 的官方網址是 http://jdbc.postgresql.org/,至於 Driver 的下載點在 http://jdbc.postgresql.org/download.html。在下載點你通常可以看到不止一種版本的 Driver,而且在該網頁下方還有一個表格製成的清單。有用過 Oracle 的人會覺得這個清單單純多了,因為在 Oracle,JDBC 有好幾種不同 Type 的版本,比如 Type 2、3 或 4,而 PostgreSQL 只有 Type 4 的版本,也就是不需要用到 Native Library 的版本。但是 PostgreSQL 有針對 JDBC 客戶端用的 VM 版本不同,出了 JDBC 2、JDBC 3 或 JDBC 4,至於你該下載哪一個版本,在下載網頁中說明的相當清楚,原則上,
所以,我們要下載的是 JDBC 3 這個版本。目前最新的版本是 JDBC3 Postgresql Driver, Version 8.3-603 (2008/3 /1)。到你看到這篇文章時,版本號次可能又增加了,請下載當下的最新版本,這個版本通常會列在下載網頁的 Current Version 該節中,請不要認為非得下載 603 這個版本不可,只要版次比這個號次大就可以了。
下載之後,理論上,你可以把它擺在你安裝 JDK 的目錄下的 jre\lib\ext,JDK 的安裝目錄我們通常稱之為 JAVA_HOME (你可以把它加到系統環境變數中),如果你在安裝時沒修改 JDK 安裝目錄的設定值,那麼在 Windows 下通常是 "C:\Program Files\Java\jdk1.6.0_03" 或是其它版次,比如說像是 "C:\Program Files\Java\jdk1.6.0_01" 等等,那麼你必須把下載下來的 JAR 檔複製一份到 C:\Program Files\Java\jdk1.6.0_03\jre\lib\ext 下,這樣 JDK 預設的 CLASSPATH 就會自動指到 PostgreSQL JDBC Driver。當然,在最正確的方式是把 JAR 檔放在任何目錄下,再設定一個叫 CLASSPATH 的環境變數,把它設定成你放 JAR 檔的 PATH,比如說,你把 JDBC Driver 放在 C:\Program Files\psqlJDBC,就把 CLASSPATH 設成 CLASSPATH="C:\Program Files\psqlJDBC\postgresql-8.3-603.jdbc3.jar"。注意,如果你的 PATH 像我一樣含有空白字元,請記得一定要用引號包圍起來,否則在編譯你的程式或執行 Java 程式時 JDK 一定會找不到 JDBC 驅動程式,而產生例外。
我們再往下,看看如果是你自己寫 Java 程式,要如何去以 SSL 編碼連上資料庫伺服器。剛才說過,JDBC 3 這個版本的驅動程式已經將 SSL 支援加入了,但是一般預設 SSL 還是關閉的。我們先從一般性的寫法開始,首先,要記得所有用到 JDBC 的 Java 程式都必須先
import java.sql;
import sql 這個套件,再來請用
Class.forName("org.postgresql.Driver");
載入 JDBC driver。再來,建立一個連結物件,Connection。建立 Connection 時,JDBC 有專屬的 URL 格式,用來指定要連結的資料庫所在位置,以及連結它的資料,格式如下:
第一種格式是連結本機資料庫時使用,database 是指你要連結的本機資料庫名稱。第二、第三種則為遠端資料庫的連接方法,host 就是主機名稱,如果你的伺服器並未在 DNS 中註冊名稱,那麼也可以用 IP 位址,IPv6 也可以,但是這是假定你的 Windows 和伺服器的作業系統都有支援 IPv6 時。port 是如果你不是使用 PostgreSQL 預設的 port 5432,那麼這裏你就要特別註名 port number。除了這些以外,你也可以用 Properties 物件來指定其餘的性質,像是 user 名、密碼 password 以及指定要使用 SSL 編碼通訊:
String url = "jdbc:postgresql://localhost/test";
Properties props = new Properties();
props.setProperty("user","fred");
props.setProperty("password","secret");
props.setProperty("ssl","true");
Connection conn = DriverManager.getConnection(url, props);
還有另一種更簡便的方法,如下:
String url = "jdbc:postgresql://localhost/test?user=fred&password=secret&ssl=true";
Connection conn = DriverManager.getConnection(url);
這個直接把性質在 URL 中指定的方法更簡便,雖然不夠正式,但是還是可以使用的。
再來這一步是最重要的。首先要說的,就算你把 ssl=true 這個性質加上來了,並不代表就可以用 SSL 連線了。由於 JDBC 和 ODBC 不一樣的,是可攜的,所以很容易可以把認證複製帶走。而 SUN 當初設計 Java 時為了安全性,訂了一個很麻煩的安全 Socket 規格,叫 JSSE。如果按照這個規格,的確可以實作完整的 SSL 認證規格。但是我們目前只想用 SSL 編碼做安全連線,並不用對伺服器或客戶端做完整的認證,因此只是做一個連線就要完全實作 JSSE 似乎是殺雞用牛刀,完全沒必要。幸好 PostgreSQL JDBC driver 設計群早就想到有這種狀況,因此,他們在 JDBC 3 driver 中附了一個僅供連線用的類別 SSLSocketFactory,只需你在 URL 中加上 sslfactory=org.postgresql.ssl.NonValidatingFactory 這個參數,就可以把 SSL 打開,建立以 SSL 編碼的安全性連線了。換句話說,剛才的簡捷 URL 設定法就要改成:
String url = "jdbc:postgresql://localhost/test?user=fred&password=secret&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory";
Connection conn = DriverManager.getConnection(url);
有關於 JDBC 程式寫作,繼續像建立查詢物件等等的後續動作,由於這篇文章主要只在介紹建立安全連線,所以我們就先跳過,過一陣子有空我再寫一篇文章說明,這篇文章的目的只在如何以 SSL 連結伺服器,這部份說明先到此為止。有興趣的朋友,可以先到 http://jdbc.postgresql.org/documentation/83/index.html 看一下 JDBC 的文件,裏面說明的很詳細。 再來就進入我們的主題,讓我們來看看如何設定 NetBeans,讓 NetBeans 的資料庫工具得以用 SSL 安全通訊方式連結伺服器。我假定在本機已安裝一套 PostgreSQL,然後試著連上本機的伺服器。至於跨過網路連接其它伺服器,只有 URL 再加上 host 即可,在這裏就跳過。我以 NetBeans 6.0 為例,同時輔以 5.5.1 正體中文版的設定方式做為說明,其實兩者除了語言上的差別以外,幾乎是完全相同的。
首先,先執行 NetBeans。先往左半邊看去,在 6.0 版可以看到左邊上方有三個頁籤,請切到「Services」頁籤,至於 5.5.1 中文版則是切到「執行環境」頁籤:
接著你可以看到左半邊的「Services」或「執行環境」頁籤,有一個樹狀結構,在 6.1 版中,有個節點叫「Databases」,而 5.5.1 中文版則為「資料庫」,這就是我們可以掛載我們的資料庫工具的節點。 接著請在這個節點上按下滑鼠右鍵,這時會出現一個下拉式選單,請點選「New Connection...」或「新增連接...」:
這時候會出現一個「New Database Connection」或者「新增資料庫連接」對話方塊,請從「Name:」或者「名稱(N):」欄位下拉,找出 PostgreSQL。6.0 版預設已經將 PostgreSQL JDBC 驅動程式安裝上來了,但是 5.5.1 中文版沒有,不用緊張,先點選「新增驅動程式...」把我們剛才下載的最近版本 JDBC 驅動程式註冊上來:
這時候出現一個「新增 JDBC 驅動程式」,請按下「加入(A)...」按鈕:
然後從檔案對話方塊中把你下載的 JDBC 驅動程式找出來,NetBeans 會自動判別出驅動程式的類別和名稱,不過,即使它沒自動找出來,你還是可以按下「尋找」按鈕把它找出來:
接著按下「確定」,回到「New Database Connection」對話方塊。這時候你會發現,在「Database URL:」或「資料庫 URL(A):」文字方塊裏,出現了一個 URL 的樣版:jdbc:postgresql://<HOST>:<PORT>/<DB>。讓我們回想前面討論的使用 JDBC 來寫 Java 程式的第三個步驟,建立一個資料庫連接物件時,要填的 JDBC 專屬 URL,就是要填在這裏的,你可以直接套入簡捷模式的 URL,也可以像下面我所填的方式。由於我所要連接的是安裝本機上的 PostgreSQL 伺服器,所以 //<HOST> 是可以省略的,<PORT> 由於我沒更改 PostgreSQL 預設的 port 5432,所以這部份也是可以省略,<DB> 要填的就是你要使用的 database,這一項就一定不可省略了。當然你也可以填入 jdbc:postgresql://localhost:5432/database 這樣的標準格式,一切看你自己。最後也是本文最重要的部份,由於要以 SSL 加密方式連接,所以要在樣版以外,再加上一個 ?ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory:
記得要填使用者名稱和密碼,要不要記住密碼隨便你,如果你比較注重安全性,那麼建議不要把這個選項打開。接著按下確定,沒有意外的話,在一串連接的動作完成後,「New Database Connection」對話方塊會自動切到「Advanced」或「進階」頁籤,這時你要選擇要使用的 schema,由於目前我只有用到 public 這個 schema,其它的都是 PostgreSQL 的系統 schema,所以由下拉式選單中點選 public:
按下確定後,就會跳出對話方塊。這時候你就會發現左半邊的「Databases」或「資料庫」節點上,多出一個已連接的資料庫的節點,你可以點選它,把它展開。這時可以看到樹狀結構展開後出現三個節點,分別是 Tables/表格、Views/檢視 和 Procedures/程序。你可以把它們展開來看看,看看伺服器中的所有物件:
這時你還可以隨便點選一個物件,比如說,點選某個資料表格,然後按下滑鼠右鍵,讓下拉式選單跳出來,選「View Data...」,這時候就可以把該資料表格內的資料顯示出來,中文沒問題,連欄位都可以是中文的,這方面我就不 demo 了,請各位自己練習。
記得我在 利用 SSL 讓 PostgreSQL 有一個安全的網路傳輸 這篇文章的最後,提到客戶端還有工作要做。事實上也就是因為各種界面的不同,而讓 SSL 連接的設定就有稍許的不同,而看起來很複雜。有些連接界面的 SSL 就在管理界面上可以直接點選,比如 ODBC,但是也有像 JDBC 這種各自為政型的界面方式,這時候你就要多多費心。網路上這方面的資料不好找,所以我打算慢慢把我所蒐集、測試過的連接方式,慢慢介紹給大家。預告一下,下一篇我將介紹和 NetBeans 連接方式大同小異的 Eclipse DTP (Data Tools Platform)。至於 Borland 的 JBuilder,由於使用者越來越少,我就不介紹了。