用戶認證和訪問控制是大多數java應用的重要安全尺度
特別是J
EE應用
Java認證和權限服務(即JAAS)
J
SE
和
的核心API
描繪表達了新的安全標准
其提供了一個可插拔的(pluggable)和富有彈性的(flexible)框架(framework)允許開發者混合不同的安全機制和豐富的已經存在各種安全方面的資源
伴隨著即將來臨的J
SE
版本的發布
它包含了許多諸如加密技術
XML安全性
公鑰機制(PKI)
Kerberos (是一個網絡附加系統/協議
可以允許用戶通過一個安全伺服器的服務來驗證 自己
象遠端登陸
遠端拷貝
系統間的相互檔拷貝和另外高風險任務的服務將被變 得相當安全和可控制
)和結盟認證(the federating identity)的增強!
JAAS將會在J
EE實現中扮演一個更加重要的角色
認證 認證就是校驗一個用戶擁有使用已經被企業用戶注冊機構證明了的身份鑒定的權限的處理過程
JAAS的認證機制建立於一整套可插拔的模塊(參看圖
)基礎上
JAAS允許不同的驗證模型在運行時可被插拔
客戶應用總是通過登陸上下文對象和JAAS交互
認證處理過程典型的要經過下面的步驟
生成一個LoginContext對象
這個LoginContext尋找配置文件以決定使用那個LoginModule
同樣
可選擇的
有可能傳遞一個CallbackHandler給LoginContext
通過調用LoginContext的login方法執行認證
它會加載預定義的LoginModule去檢驗是否用戶可以被認證
如果用戶被認證
那麼用規則和標識和其所屬項進行關聯
或者在登陸失敗的情況下跑出一個LoginException
使用LoginContext的logout方法進行注銷登陸
在JAAS中
登陸是一個兩階段(two
phase)的處理過程
第一階段是
登陸(login)
階段(就像上面
所描述的)
這個階段唯一的任務是認證
只要處理過程成功通過這個階段
認證處理過程就進入了
提交(commit)
階段(如上步驟
)
這一階段LoginModule的commit方法被調用去關聯所屬子項相關的規則和標識
在JAAS中一個所屬子項表示一個認證實體
比如一個人或者一台設備
它包含了一整套法則和安全相關的屬性諸如密碼和加密密鑰
在JAAS體系結構中
所屬子項和其所附屬的相關權限
扮演了重要的角色在認證過程當中
所有的認證模塊當中
LoginModule是事實上的認證機制的借口
雖然LoginModule決沒有得到直接調用客戶應用的機會
但是他經由一個可插拔的模塊提供了一個認證的具體類型
其實現了認證的算法並且決定實際的認證過程是怎樣被執行的
SUN提供了幾個默認的LoginModule 實現
在
security
auth
module包裡有諸如JndiLoginModule
Krb
LoginModule
UnixLoginModule和NTLoginModule等幾個LoginModule實現
因為JAAS登錄結構體系是可擴展的
所以你只要在配置文件中指定使用哪個LoginModule模塊就可以幾乎全部插入任何LoginModule模塊
如下即為一個配置文件的例子
MySample {
com
sample
module
MyLoginModule required debug=true;
};
這裡MySample是登錄上下文環境(login context)的名字
當你生成一個新的LoginContext開始認證過程時它會被傳入LoginContex的構造函數中
依據配置塊提示
那個文本塊提醒JAAS有關LoginModule在登錄過程中應該被用來執行認證
另外
對於LoginModule
任何關於他的選項也可以在這裡被指定
在執行登錄這一步驟的過程中
CallbackHandler類被LoginModule類用來跟用戶通信已便於取得認證信息
CallbackHandler類處理三種類型的回調(Callback)
NameCallback
提示用戶輸入一個用戶名
PasswordCallcack
提示輸入密碼
TextOutputCallback
報告錯誤
警告或則發送給用戶一些其他信息
授權是決定是否認證的用戶可以執行一些動作的工作
例如訪問一處資源
因為JAAS建立於已經存在的Java安全模型的基礎上
故這個過程時基於策略的
策略配置文件實質上包含了一系列的入口
諸如
Keystore
和/或
grant
grant入口包含了所有的權限
他是通過認證的代碼或則法則被授予可以進行安全敏感的操作
例如
訪問一個具體的Web頁面或則本地的文件
JAAS支持基於法則的策略入口
賦權入口基本格式如下
grant Codebase
codebase_URL
Signedby
signer_name
Principal principal_class_name
principal_name
Principal principal_class_name
principal_name
… {
permission permission_class_name
target_name
action
permission permission_class_name
target_name
action
…
}
上面格式中
動作(action)
可能是必需的或則可能被忽略依賴於權限類型
在JAAS體系結構中
策略對象表達了一個Java應用環境的系統安全策略和在任何時間事實上只有一個策略對象
依據Java
SDK文檔
默認的策略實現是sun
security
provider
PolicyFile
其中策略被指定在一個或多個策略配置文件裡
只要用戶被認證
授權經由Subject
doAs方法發生
或者從Subject類的靜態方法doAsPrivileged
doAS方法用當前的AccessControlContext動態和子項並且同時調用run方法去執行動作
他導致安全驗證
權限驗證過程通過下面的步驟在圖
:
就像LoginModule
策略也是可插拔的模型
你可以掛上其它的策略實現通過在java
security的屬性文件中改變
policy
provider=sun
security
provider
PolicyFile
到一個你項使用的策略類
Extend JAAS JAAS建立於已經存在的Java安全模型的頂端
其基於
CodeSource
和平面文本格式策略文件實現
這可能對企業應用是不夠用的
你可能想使用可定制的安全倉庫
對於JAAS的其它實現
諸如LDAP(輕型目錄訪問協議)
數據庫或者其他文件系統
它可以通過編寫你自己的可定制模塊被完成
感謝JAAS的可插拔的特性
然而
這需要對模塊和JAAS中的處理過程有完善的理解
同時你必須做許多編碼去覆寫相關的類
並且處理好配置和策略兩種文件
理想情況下
我們願意能夠擴展JAAS以一個更加容易的方式以便於無論何時一個可定制的安全知識庫或者不同的訪問控制機制改變或者必須去增加時
你能夠只開發和插入這些不同的小模塊(即
適配器)去適應這些新的變化和需求
並且在最好的情況下
不必去理解和熟悉JAAS處理過程的細節
同樣
我們也願意能夠去做這些變化僅僅通過改變一個配置文件
另一個目標是我們的JAAS擴展組件能夠被使用在不同的J
EE應用中—獨立的或者Web上的
圖
描述了JAAS擴展組件的設計意圖
我們的JAAS擴展組在實現可定制的LoginModule和策略模塊時充分件利用了JAAS插拔式的體系結構
這些模塊中
我們委派數據請求到適配器
這些適配器的每個對於諸如數據取回的簡單任務是隔離的
所以你可以快速地使用不同的安全知識或者算法開發不同的適配器而不是嘗試去實現不同的LoginModule或者策略模塊
它們更加復雜並且需要更多的努力
你可以從/java/sourcec
cfm
下在完整的源瑪
實現的AuthLoginModule類 AuthLoginModule類是我們定制的LoginModule實現
LoginModule類是在JAAS中是一個可插拔組件並且服務於兩個目的
鑒定認證用戶
如果認證成公
則用相關的負責人信息或者證書更新主題
LoginModule有
個方法去實現功能
讓我們關注一下login()方法
這個方法被調用以認證主題並且主要作兩件事情
包含用戶名和密碼
典型地
LoginModule要調用CallbackHandler類的handle方法去得到用戶名和密碼
通過和數據源中的比較校驗密碼
LoginModule從Callbacks取回用戶名和密碼
(其默認期望用戶接口的某種排序)
這一點對於一個簡單的演示程序或者就在命令行
可是他對於一個J
EE應用來說不太實用
例如
對於大多數的Web應用
用戶名和密碼將比較典型的從一個form中讀出
在這種情況下
使用JAAS認證會比較困難
考慮我們不直接使用LoginModule
解決方案是實現一個可定制的CallbackHandler類
他會接收用戶名和密碼然後遞交它們給LoginModule
所以他沒有必要提示用戶輸入信息
以下示例説明用戶信息如何從JSP或者Servlet中傳遞
String userName = request
getParameter (
user
);
String password = request
getParameter(
password
);
LoginContext context = new LoginContext (
MySample
new AuthCallbackHandler (userName
password));
一旦擁有了用戶名和密碼在手
AuthLoginModule類
我們的LoginModule類的定制實現
會經由LoginSourceAdapterFactory實例化LoginSourceAdapter並同時委派實際的認證過程到資源適配器
適配器只不過是一個簡單的類
其從一個具體的數據適配器(比如數據庫或者LDAP
或者一些別的系統)領取用戶信息
在
提交
階段
AuthLoginModule類從LoginSourceAdapter類取回相關的信息並且把他們和主題相關聯
LoginSourceAdapter類
LoginSourceAdapter類是一個認證目的的資源適配器的接口
它有
個需要實現的方法
void initialize(Hashtable parameters):initialized方法被調用來以相關的參數初始化適配器
此方法在對象生成後立即被調用並且優先於任何對其他方法的調用
boolean authenticate(String username
char[] password):此認證方法被調用來認證用戶
String[] getGroupNames (String userName):getGroupNames方法被調用來在認證成功後得到相關的主要信息
void terminate ():這個方法在LoginModule類的logout方法被執行後調用
它給適配器做一些清理工作的機會
AuthPoli
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27602.html