J2EE 探索者: 用JAAS 和 JSSE 實現 Java 安全性

ouhennb發表於2009-07-03
可以說隨著 J2EE Web 應用程式安全體系結構的引入,我們不斷從近 10 年的反覆試驗有所收穫,事實也表明了這一點。J2EE 安全框架由三個 API 組成:Java 認證和授權服務(JAAS)、Java 安全套接字擴充套件(JSSE)和 Java 加密擴充套件(Java Cryptography Extension,JCE)。雖然 JCE 是一個有意思和重要的 API,但是它與我們所關注的安全 Web 應用程式開發的“三大項”――認證、授權和傳輸――並不特別相關。所以在本月的專欄中我們將集中講述 JAAS 和 JSSE。
  JAAS 和 JSSE 概述

  JAAS 提供了一種靈活的、說明性的機制,用於對使用者進行認證並驗證他們訪問安全資源的能力。JSSE 定義了通過安全套接字層(SSL)進行安全 Web 通訊的一種全 Java 的機制。通過結合這兩種技術,可以使我們的應用程式:

  驗證使用者就是他或者她所宣稱的那個人(認證)。

  保證允許他或者她訪問所要求的資源(授權)。

  通過安全網路連線進行完整的資訊交換(傳輸)。

  現在,我們來看每一個基礎的功能元件。

  用 JAAS 進行認證

  JAAS 建立在一種稱為可插入的認證模組(Pluggable Authentication Module,PAM)的安全體系結構之上。PAM 的體系結構是 模組化的,這意味著它設計為可以通過交換模組,支援從一個安全協議元件無縫地轉換到另一個協議元件。這個框架中定義良好的介面使得無需改變或者干擾任何現有的登入服務就可以加入多種認證技術和授權機制。PAM 體系結構可以整合範圍廣泛的認證技術,包括 RSA、DCE、Kerberos 以及 S/Key,因而 JAAS 也可以整合這些技術。此外,這個框架與基於智慧卡的認證系統和 LDAP 認證相容。

  就像許多 Java 2 平臺技術一樣,JAAS API 定義了應用程式程式碼與將要執行業務邏輯的物理實現之間乾淨的抽象。這個抽象層不用重新編譯現有的應用程式程式碼就可以作為登入模組的執行時替代。特別是,應用程式寫到 LoginContext API,而認證技術提供程式則寫到 LoginModule 介面。在執行時, LoginContext 將讀取配置檔案以確定應使用哪一個(一些)登入模組對訪問特定應用程式的使用者進行認證。

  JAAS 所使用的認證方案以兩種非常重要的實體為基礎:principal 和 subject。實際被認證的人或者服務稱為 subject。 principal是一個惟一的實體,比如個人或者組的名字、帳號、社會安全號或者類似的惟一標識。為了惟一標識一個 subject(這是認證的關鍵部分),一個或者多個 principal 必須與這個 subject 相關聯。最後,一個 subject 可能擁有安全相關的屬性,稱為 憑證(credential)。憑證可以是從簡單的密碼到複雜的加密金鑰的任何東西。

  應用程式通過例項化一個 LoginContext 物件開始認證過程。 LoginContext 查詢一個配置檔案以確定進行認證所使用的一種(或者多種)認證技術以及相應的一個(或者多個) LoginModule 。一個非常簡單的 LoginModule 可能會提示輸入使用者名稱和密碼並對它們進行驗證。高階一點的可能會使用現有的作業系統登入身份進行身份驗證。理論上,甚至可以將一個 JAAS LoginModule 構建成與指紋識別器或者虹膜掃描器互動。

  用 JAAS 進行授權

  認證只是 Java 安全框架任務的一半。當使用者的身份被確認後,必須對他或者她的訪問許可權進行檢查。只有確認了適當的許可權後,使用者才可以訪問安全的系統或者資源。

  換一種說法,驗證了使用者或者服務的身份後,就建立一個 Subject 物件來表示經過驗證的實體。然後 JAAS 將這個物件傳遞給任何為保護對敏感系統或資源的訪問而建立的授權元件。

  要確定授權,可以向 Java 2 Security Manager 提供 Subject 及其 Principal s,以及 Subject 要執行的特權操作(讀/寫到檔案系統、資料庫訪問,等等)。Security Manager 會諮詢與 Principal s 和許可權相關聯的策略檔案。 如果一個 Subject 的 Principal s 具有執行指定操作的許可權,那麼就對這個 Subject 授權並允許操作,否則就會拒絕這項操作並丟擲一個 SecurityException 。

用 JSSE 進行安全傳輸

  有了 JAAS ,我們就可以識別訪問系統的使用者並限制他們只能訪問授權使用的那部分系統。雖然 JAAS 是邁向安全 Web 應用程式堅實的第一步,但是如果沒有安全傳輸,那麼應用程式安全性仍然是不完整的。

  這裡,我們仍然是以明文形式――即 HTTP、TCP/IP、FTP等――傳遞安全資訊(包括認證資訊)。所以我們需要保證資料在傳輸時不會被未授權的人訪問。我們還需要保證資料在到達之前,沒有在傳輸過程中修改過,不管這種修改是有意的還是無意的。我們可以利用安全套接字層(SSL)和傳輸層安全性(Transport Layer Security,TLS)協議實現這兩種功能。

  SSL 和 TLS 不是特定於 Java 的協議,它們是為維護通過套接字的資料的完整性和私密性而設計的網路層協議。Java 安全套接字擴充套件(JSSE)利用 SSL/TLS 可以進行安全的 Internet 通訊,它提供了一個具有完整功能的應用程式框架――一個 Java 版本的 SSL 和 TLS 協議,這些功能包括資料加密、伺服器認證、訊息完整性,等等。使用 JSSE,我們可以定義執行任意應用程式協議――包括 HTTP、TCP/IP、FTP,甚至 Telnet――的客戶機與伺服器之間的安全套接字連線。從資料加密的角度看,JSSE 結合了許多與 JCE 中使用的同樣的概念和演算法。不過更重要的是,在簡單流套接字 API 背後,它會在必要時自動使用它們。

  要利用 JSSE API,我們只需要做簡單的幾件事。首先我們需要獲得 JSSE 提供程式(請參閱 參考資料)。其次,我們需要從一個 JSSE 套接字工廠而不是直接從 java.net.Socket 類獲得套接字。客戶端程式碼從 SSLSocketFactory 獲取套接字,而伺服器端程式碼從 SSLServerSocketFactory 獲取套接字。通過從這些工廠獲取套接字,我們就可以利用 JSSE 提供程式提供的框架,而不是像 java.net 包允許我們所作的那樣,簡單地建立標準的、不安全的套接字。

  有關 JSSE 的更多細節,請參閱 參考資料。

  結束語

  Java 平臺以其岩石般堅固的安全性聞名。每一年 Java 安全性框架都會變得更靈活和更健壯,JAAS 和 JSSE 的加入表明這個傳統將會繼續發揚光大。

相關文章