摘要
Java Authentication Authorization Service(JAAS
Java驗證和授權API)提供了靈活和可伸縮的機制來保證客戶端或服務器端的Java程序
Java早期的安全框架強調的是通過驗證代碼的來源和作者
保護用戶避免受到下載下來的代碼的攻擊
JAAS強調的是通過驗證誰在運行代碼以及他/她的權限來保護系統面受用戶的攻擊
它讓你能夠將一些標准的安全機制
例如Solaris NIS(網絡信息服務)
Windows NT
LDAP(輕量目錄存取協議)
Kerberos等通過一種通用的
可配置的方式集成到系統中
本文首先向你介紹JAAS驗證中的一些核心部分
然後通過例子向你展示如何開發登錄模塊
你是否曾經需要為一個應用程序實現登錄模塊呢?如果你是一個比較有經驗的程序員
相信你這樣的工作做過很多次
而且每次都不完全一樣
你有可能把你的登錄模塊建立在Oracle數據庫的基礎上
也有可能使用的是NT的用戶驗證
或者使用的是LDAP目錄
如果有一種方法可以在不改變應用程序級的代碼的基礎上支持上面提到的所有這一些安全機制
對於程序員來說一定是一件幸運的事
現在你可以使用JAAS實現上面的目標
JAAS是一個比較新的的Java API
在J
SE
中
它是一個擴展包
在J
SE
中變成了一個核心包
在本文中
我們將介紹JAAS的一些核心概念
然後通過例子說明如何將JAAS應用到實際的程序中
本文的例子是根據我們一個基於Web的Java應用程序進行改編的
在這個例子中
我們使用了關系數據庫保存用戶的登錄信息
由於使用了JAAS
我們實現了一個健壯而靈活的登錄和身份驗證模塊
Java驗證和授權
概論
在JAAS出現以前
Java的安全模型是為了滿足跨平台的網絡應用程序的需要而設計的
在Java早期版本中
Java通常是作為遠程代碼被使用
例如Applet
因此最初的安全模型把注意力放在通過驗證代碼的來源來保護用戶上
早期的Java安全機制中包含的概念
如SercurityManager
沙箱概念
代碼簽名
策略文件
多是為了保護用戶
JAAS的出現反映了Java的演變
傳統的服務器/客戶端程序需要實現登錄和存取控制
JAAS通過對運行程序的用戶的進行驗證
從而達到保護系統的目的
雖然JAAS同時具有驗證和授權的能力
在這篇文章中
我們主要介紹驗證功能
通過在應用程序和底層的驗證和授權機制之間加入一個抽象層
JAAS可以簡化涉及到Java Security包的程序開發
抽象層獨立於平台的特性使開發人員可以使用各種不同的安全機制
而且不用修改應用程序級的代碼
和其他Java Security API相似
JAAS通過一個可擴展的框架
服務提供者接口(Service Provider Interface
SPI)來保證程序獨立於安全機制
服務提供者接口是由一組抽象類和接口組成的
圖一中給出了JAAS程序的整體框架圖
應用程序級的代碼主要處理LoginContext
在LoginContext下面是一組動態配置的LoginModules
LoginModule使用正確的安全機制進行驗證
圖一給出了JAAS的概覽
應用程序層的代碼只需要和LoginContext打交道
在LoginContext之下是一組動態配置的LoginModule對象
這些對象使用相關的安全基礎結構進行驗證操作
圖一 JAAS概覽
JAAS提供了一些LoginModule的參考實現代碼
比如JndiLoginModule
開發人員也可以自己實現LoginModule接口
就象在我們例子中的RdbmsLonginModule
同時我們還會告訴你如何使用一個簡單的配置文件來安裝應用程序
為了滿足可插接性
JAAS是可堆疊的
在單一登錄的情況下
一組安全模塊可以堆疊在一起
然後被其他的安全機制按照堆疊的順序被調用
JAAS的實現者根據現在一些流行的安全結構模式和框架將JASS模型化
例如可堆疊的特性同Unix下的可堆疊驗證模塊(PAM
Pluggable Authentication Module)框架就非常相似
從事務的角度看
JAAS類似於雙步提交(Two
Phase Commit
PC)協議的行為
JAAS中安全配置的概念(包括策略文件(Police File)和許可(Permission))來自於J
SE
JAAS還從其他成熟的安全框架中借鑒了許多思想
客戶端和服務器端的JAAS
開發人員可以將JAAS應用到客戶端和服務器端
在客戶端使用JAAS很簡單
在服務器端使用JAAS時情況要復雜一些
目前在應用服務器市場中的JAAS產品還不是很一致
使用JAAS的J
EE應用服務器有一些細微的差別
例如JBossSx使用自己的結構
將JAAS集成到了一個更大的安全框架中
而雖然WebLogic
x也使用了JAAS
安全框架卻完全不一樣
現在你能夠理解為什麼我們需要從客戶端和服務器端的角度來看JAAS了
我們將在後面列出兩種情況下的例子
為了使服務器端的例子程序更加簡單
我們使用了Resin應用服務器
核心JAAS類
在使用JAAS之前
你首先需要安裝JAAS
在J
SE
中已經包括了JAAS
但是在J
SE
中沒有
如果你希望使用J
SE
你可以從SUN的官方站點上下載JAAS
當正確安裝了JAAS後
你會在安裝目錄的lib目錄下找到jaas
jar
你需要將該路徑加入Classpath中
(注
如果你安裝了應用服務器
其中就已經包括了JAAS
請閱讀應用服務器的幫助文檔以獲得更詳細的信息)
在Java安全屬性文件java
security中
你可以改變一些與JAAS相關的系統屬性
該文件保存在<jre_home>/lib/security目錄中
在應用程序中使用JAAS驗證通常會涉及到以下幾個步驟
創建一個LoginContext的實例
為了能夠獲得和處理驗證信息
將一個CallBackHandler對象作為參數傳送給LoginContext
通過調用LoginContext的login()方法來進行驗證
通過使用login()方法返回的Subject對象實現一些特殊的功能(假設登錄成功)
下面是一個簡單的例子
LoginContext lc = new LoginContext(
MyExample
);
try {
lc
login();
} catch (LoginException) {
// Authentication failed
}
// Authentication successful
we can now continue
// We can use the returned Subject if we like
Subject sub = lc
getSubject();
Subject
doAs(sub
new MyPrivilegedAction());
在運行這段代碼時
後台進行了以下的工作
當初始化時
LoginContext對象首先在JAAS配置文件中找到MyExample項
然後更具該項的內容決定該加載哪個LoginModule對象(參見圖二)
在登錄時
LoginContext對象調用每個LoginModule對象的login()方法
每個login()方法進行驗證操作或獲得一個CallbackHandle對象
CallbackHandle對象通過使用一個或多個CallBack方法同用戶進行交互
獲得用戶輸入
向一個新的Subject對象中填入驗證信息
我們將對代碼作進一步的解釋
但是在這之前
讓我們先看代碼中涉及到的核心JAAS類和接口
這些類可以被分為三種類型
普通類型 Subject
Principal
憑證
驗證 LoginContext
LoginModule
CallBackHandler
Callback
授權 Policy
AuthPermission
PrivateCredentialPermission
上面列舉的類和接口大多數都在javax
security
auth包中
在J
SE
中
還有一些接口的實現類在com
sun
security
auth包中
普通類型
Subject
Principal
憑證
Subject類代表了一個驗證實體
它可以是用戶
管理員
Web服務
設備或者其他的過程
該類包含了三中類型的安全信息
身份(Identities)
由一個或多個Principal對象表示
公共憑證(Public credentials)
例如名稱或公共秘鑰
私有憑證(Private credentials)
例如口令或私有密鑰
Principal對象代表了Subject對象的身份
它們實現了java
security
Principal和java
io
Serializable接口
在Subject類中
最重要的方法是getName()
該方法返回一個身份名稱
在Subject對象中包含了多個Principal對象
因此它可以擁有多個名稱
由於登錄名稱
身份證號和Email地址都可以作為用戶的身份標識
可見擁有多個身份名稱的情況在實際應用中是非常普遍的情況
在上面提到的憑證並不是一個特定的類或借口
它可以是任何對象
憑證中可以包含任何特定安全系統需要的驗證信息
例如標簽(ticket)
密鑰或口令
Subject對象中維護著一組特定的私有和公有的憑證
這些憑證可以通過getPrivateCredentials()和getPublicCredentials()方法獲得
這些方法通常在應用程序層中的安全子系統被調用
驗證
LoginContext
在應用程序層中
你可以使用LoginContext對象來驗證Subject對象
LoginContext對象同時體現了JAAS的動態可插入性(Dynamic Pluggability)
因為當你創建一個LoginContext的實例時
你需要指定一個配置
LoginContext通常從一個文本文件中加載配置信息
這些配置信息告訴LoginContext對象在登錄時使用哪一個LoginModule對象
下面列出了在LoginContext中經常使用的三個方法
login () 進行登錄操作
該方法激活了配置中制定的所有LoginModule對象
如果成功
它將創建一個經過了驗證的Subject對象
否則拋出LoginException異
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27525.html