JAAS 基礎認證和授權機制
作者:Bill Kemp, Peter Holditch
安全性是所有可以用來對資源進行保護和驗證的機制。有很多種安全模型都可以用來對數據提供保護。這些安全模型可以使用加密、訪問控制或其他安全方法。授權
(Authorization),或稱為訪問控制,可以使用不同的安全服務來對資源進行保護:一種方法是Java認證和授權服務(Java
Authentication and Authorization Service,JAAS),另外一種方法是Windows
2000的活動目錄(Active Directory)。本文著重于介紹JAAS安全服務。
認證和授權是兩種最基本的安全機制。認證就是簡單地對一個實體的身份進行判斷;而授權則是向實體授予對數據資源和信息訪問權限的決策過程。JDK 1.4已經集成了一項提供認證和授權功能的標準服務,該服務就稱為Java認證和授權服務。
JAAS通過一個配置文件來定義認證機制,而根本不需要使用任何代碼。認證機制之所以需要參數是為了確定用戶的身份(對用戶進行標識)。用來對用戶進行認
證的參數,例如每種認證機制中使用的用戶名和口令,都稱為驗證信息。Subject表示我是的那個人,但是我們也可以使用驗證信息(可以理解為駕駛執照)
向巡警證明自己的身份,并使用另外一個驗證信息(可以理解為護照)向邊防警察證明自己的身份。授權只能在認證之后進行,因為在向用戶開放保護資源的訪問權
限之前,必須對用戶的身份進行確認。JAAS框架對由配置文件指定的認證模塊進行了包裝。如果認證成功,就會返回一個包含驗證信息的Subject,認證
機制所返回的這個驗證信息會用于授權過程。
JAAS首先使用一個LoginContext類來查找配置文件中的內容,這些內容可以用來對LoginModules進行初始化(見圖1)。所有
LoginContext沒有指定的初始化參數都會包含在配置文件中。LoginContext還會向LoginModule傳遞一個
CallbackHandler,CallbackHandler又會回調適當的應用程序,從而獲得其他認證信息。例如,如果LoginContext在
創建CallbackHandler時沒有指定用戶名和口令,而LoginModule又的確需要這些內容,那么LoginModule就會使用
CallbackHandler來回調LoginContext,以重新獲得所需要的信息。
為了讓驗證信息可用于登錄,LoginContext還可以向LoginModule傳遞Subject。
圖1 JAAS初始化序列圖

在創建LoginContext時,完成LoginModule的初始化之后,LoginContext就可以調用login(
)方法(見圖2),它會對Subject進行認證。登錄過程需要經過一個由LoginModule組成的菊花鏈,根據配置文件的內容,每一步都需要一個不
同類型的驗證信息。配置文件還可以指定可選而非必須的LoginModule的配置。LoginModule會完成一個兩階段的登錄過程:第一個階段是登
錄過程調用LoginModule的login( )方法;第二個階段是調用commit( )或abort( )方法完成登錄過程。commit(
)過程是當所有其他LoginModule完成自己的login(
)方法之后才在登錄過程中被調用的,然后最后一個LoginModule會調用commit方法,之后是下一個,依此類推。如果login(
)方法不能成功執行,就會調用abort方法來清除已經執行的操作。如果所有必須的commit( )方法都成功完成了,那么登錄過程也就成功地完成了。
圖2 JAAS登錄序列圖

授權過程需要使用在登錄過程中確定的驗證信息,因此,認證過程通常都是在Subject類中實現的,這并沒有什么可奇怪的。Subject類會使用
PrivilegedAction類來執行授權的過程。另外,還有一個擴展的PrivilegedAction類對要進行訪問控制的資源進行了包裝。不管
驗證信息是否有權對資源進行訪問,這都是在安全策略文件中定義的。Java安全管理程序會首先讀取適當的安全策略文件,并對權限和驗證信息進行分析。然
后,安全管理程序會根據這些權限和驗證信息使用PrivilegedAction類對資源進行授權(或禁止訪問)。如果該資源不允許一個特定的驗證信息訪
問,就會觸發一個訪問異常。
在WebLogic中使用JAAS
WebLogic Application Server(WLS)7.0并沒有對JAAS進行任何修改,JAAS依然是一個獨立的擴充框架。WLS
7.0包含了自己的認證和授權機制,它并不需要策略文件。配置文件會對WLS LoginModule進行定義,使其用來包裝WLS的認證機制。WLS
LoginModule通常需要一個用戶名、一個口令以及一個指向適當WLS服務器的URL。WLS
7.0還包含了一種授權機制,可以對映射資源和角色進行授權。由于WLS
7.0在WebLogic的安全框架中實現了一種授權機制,因此策略文件和Java安全管理程序都不需要定義。在調用PrivilegedAction類
時,需要使用weblogic.security.Security類。
WebLogic 7.0給出了一個例子來展示如何執行基于JAAS的認證和授權,該例是在一個Java客戶端應用程序中調用EJB來使用JAAS授權開放對資源的訪問限制。這個例子對下面Sun的例子稍微進行了修改:
http://java.sun.com/j2se/1.4/docs/guide/security/jaas/JAASRefGuide.html#Sample.
這個例子包括一個JAAS配置文件,該文件指定了以下內容:EJB客戶端用來執行認證的LoginModule的類名;用來搜集客戶端證書和認證服務器的
URL的CallbackHandler;一個PrivilegedAction類,該類包含了執行EJB訪問操作的代碼;以及一個客戶端應用程序,該程
序會創建一個LoginContext,調用login(
)方法,并通過weblogic.security.Security.runAs方法來調用PrivilegedAction類。這個例子的流程如圖3
所示。你可以查看/weblogic700/samples/server/src/examples/security/jaas文件來參考完整的例
子。本文后面的內容會參考這個例子,從遠程客戶端的角度來討論WLS中基于JAAS的認證和授權,并將其與服務器端的組件(例如servlet)進行比
較。
圖3 WLS 7.0的認證機制

Java客戶端認證
需要直接訪問WebLogic Server上的EJB或JMS
Destination的客戶端應用程序使用一個單獨的Java客戶端認證程序進行認證。BEA在WLS
7.0版中提供了一個客戶端的例子,它使用一個JAAS策略文件sample_jaas.config為應用程序指定一個LoginModule:
weblogic.security.auth.login.UsernamePasswordLoginModule。該文件的內容如下:
Sample {
weblogic.security.auth.login.UsernamePasswordLoginModule required debug=false;
};
UsernamePasswordLogin-
Module的代碼沒有包含在示例包中,不過類文件位于weblogic.jar中。代碼的詳細內容見http:
//edocs.bea.com/wls/docs70/security/cli_apps.html#1096287。
它使用weblogic.security.auth.Authenticate類(WebLogic專用的類)來對通過URLCallback指定給
LoginModule的實例進行認證。該應用程序的CallbackHandler提供了服務器的URL,服務器通過自己已配置的
Authentication Provider進行認證。
LoginModule會向CallbackHandler傳遞NameCallback和PasswordCallback來獲得客戶端的用戶名和口
令,其中該客戶端開始了應用程序。一旦用戶通過認證,LoginContext就會將Subject傳遞給LoginModule。然后,應用程序使用
LoginContext.getSubject方法獲得認證過的Subject。Subject中包含了WebLogic
驗證信息--它可以是一個WLSUser,也可以是一個WLSGroup--它會在把Subject傳遞給Security.runAs方法時用來進行認
證。整個JAAS認證過程是由應用程序在實例化LoginContext類并調用LoginContext.login(
)方法時進行初始化的。LoginContext會尋找一個已經裝載了在JAAS策略文件中發現的信息的Configuration對象。它使用
Configuration來創建一個LoginModule的實例,該實例會用于此后的認證過程。
// Create LoginContext; specify username/password login module
loginContext = new LoginContext("Sample", new SampleCallbackHandler(username, password, url));
這個LoginContext的實例化過程會定位一個在Configuration中找到的LoginModule并對其進行實例化,它使用
"Sample"名字在Configuration中查找LoginModule,并將SampleCallbackHandler傳遞給它的初始化方
法。從sample_jaas.config文件的內容中,你可以看到LoginContext會對一個
UsernamePasswordLoginModule的實例進行實例化,從而進行認證。
根據WebLogic文檔,在WLS
7.0版本中并不推薦使用weblogic.jndi.Environment類。然而,該例子中提供的LoginModule使用
weblogic.jndi.Environment對象,通過向Authenticate.authenticate方法傳遞Environment來
執行認證。其中Environment中包括用戶名、口令以及服務器的URL。這是一個很明顯的矛盾,因此我們還要在其中加入LoginModule的可
插入特性這一優點。示例LoginModule的機制,也就是Authenticate類的用法,對于客戶端應用程序自己試圖向WebLogic服務器進
行認證時是不可見的。由于LoginModule是可插入認證模塊(Pluggable Authentication
Module,PAM)的一個實例,因此它可以方便地進行替換或重寫,而不會影響到客戶端的應用程序。這是展示LoginModule可插入特性是如何防
止開發脆弱的應用程序代碼的一個很好的例子。
Authenticate.authenticate方法會連接到在URL中指定的WebLogic服務器上,并可以向服務器傳遞Subject或
Environmet(其中包含了證書),從而由為服務器的WebLogic安全區域配置的Authentication提供程序進行認證。服務器的安全
成員域中配置的Authentication提供程序也實現了LoginModule。Authentication提供程序的實現可以使用各種技術實現
認證,例如LDAP或關系數據庫。如果認證成功,Authentication提供程序就向Subject中增加認證過的Principal。在將驗證信
息加入Subject之前,它會向驗證信息驗證器發起一個請求,從而對驗證信息進行數字簽名。這樣,在調用Security.runAs返回
Subject并試圖執行關鍵授權檢查時,可以防止惡意的客戶端篡改所返回的Subject中嵌入的驗證信息。驗證信息驗證器會在授權過程中進行查詢,從
而確保所返回的Subject和在認證過程中進行數字簽名過的Subject完全相同。
基于瀏覽器的認證
即便不是大多數,也有很多基于WebLogic的應用程序是通過基于瀏覽器的客戶端來訪問的。這些應用程序通常由servlet、JSP、EJB等組成。
對這些應用程序的認證在元素中定義為BASIC或者FORM,是Web應用程序中web.xml部署描述文件中的元素,可以表示應用程序的初始訪問頁。例
如:
BASIC
當我們使用其中一個方法對Web客戶端進行認證時,Web容器根據客戶端的行為調用Web安全框架,并訪問Authentication
提供程序。這種機制的結果是生成了一個JAAS
Subject,其中包含一個經過認證的驗證信息,保存在一個內部會話對象之中。從該客戶端發來的后續請求通過HttpRequest中傳來的
cookie中的會話ID,就可以在內部會話中定位這個Subject,從而完成授權。此處的要點在于,WebLogic上的資源容器,像Web容器,也
要使用基于JAAS的認證,根據Web客戶端的行為,調用Authentication提供程序,獲取一個填充有經過認證的驗證信息的Subject。
Authentication提供程序使用的LoginModule并沒有在JAAS配置文件中配置,這一點與Java客戶端的例子不同。通過管理控制臺
將Authentication提供程序增加到活動的安全成員域中,就可以實現對Authentication提供程序的配置。WLS 7.0
默認配置的Authentication提供程序和LoginModul都是即裝即用的,使用了一個內嵌的LDAP服務器。服務器端用來認證基于Web的
客戶端的LoginModule就是Java客戶端應用程序的UsernamePasswordLoginModule調用
Authenticate.authenticate方法傳遞Subject和Environment對象進行認證時使用的那個LoginModule。
這個Subject沒有傳回Web客戶端,而是由Web容器保存在內部會話對象中,稍后通過會話ID訪問。
基于JAAS的授權
盡管WLS中的授權沒有使用JAAS的Subject.doAs方法,它仍然是基于JAAS
Subject的。要求訪問受保護的WebLogic資源的應用程序通過weblogic.security.Security.runAs方法請求訪
問。Subject和PrivilegedAction被傳遞給這個WLS安全框架方法,以執行有關一項WebLogic資源的任務。
WebLogic資源
通過Jave安全策略文件中的安全策略,我們可以對Java系統資源進行保護,而WebLogic的資源與此不同,對這些資源的保護是通過將
WebLogic角色與WebLogic資源關聯起來的安全策略進行的。一項WebLogic資源定義為一個結構化的對象,表示服務器端實體,可以保護這
些實體拒絕未經授權的用戶進行訪問。WebLogic資源的例子有:EJB方法、servlet以及JMS
Destination。有關更多可以用WebLogic角色保護的WebLogic資源類型實例,請參看http:
//edocs.bea.com/wls/docs70/dvspisec/atz.html#1134702處的文檔,
WebLogic角色
WebLogic角色的概念是在WLS
7.0中建立的,它代替了以前發布的WebLogic中基于ACL的授權。根據WLS的文檔,一個角色定義為一個抽象的邏輯用戶集合,與組的概念類似。但
是角色與組不一樣,因為角色是根據用戶名、組成員以及時間動態更改的。角色與資源一起用,可以創建WebLogic安全策略。基于JAAS的安全策略在
Java安全策略文件中定義,其作用是授權允許訪問codebase、簽名以及驗證信息的權限。將WebLogic角色與WebLogic資源關聯在一
起,就建立了一個WebLogic安全策略。WebLogic在應用安全策略時并不會考慮Java的策略文件。只要當決定對某項資源的訪問權限時,一個用
戶在這項資源的安全策略定義的角色中,那么這個用戶就可以訪問這項資源。
WebLogic角色可以是全局的,即可以將角色與所有的WebLogic資源關聯;也可以是局部的,即與特定的WebLogic資源關聯。全局角色通過
管理控制臺定義。安全策略是用局部角色,通過部署描述文件為Web應用程序和EJB動態創建的。對于Web應用程序組件,這些角色的聲明及與資源的關聯是
在web.xml文件;而對于EJB,則是ejb-jar.xml文件的元素。聲明好的角色分別通過提供商特定的部署描述文件、weblogic.xml
和weblogicejb-jar.xml,用元素賦予Principals。控制臺中也可以配置動態角色,不過控制臺改變之后,組件的部署描述文件不會
跟著改變。RoleMapper完成的工作是在部署的時候將賦予Principal的角色關聯起來。
WebLogic授權
當應用程序通過調用Security.runAs方法執行PrivilegedAction時,Java客戶端應用程序的授權過程就開始了(見圖4)。當
調用這個方法時,應用程序將認證過的Subject和PrivilegedAction傳遞給WebLogic安全框架。在WLS中,
PrivilegedAction內部激活了一個EJB方法,SampleAction.java,調用的身份標識就是已經通過認證的Subject。服
務器上的EJB容器從PrivilegedAction的上下文中的客戶端EJB
stub對象那里接收到請求。然后調用服務器上的安全框架,確定是否允許該Subject訪問這個EJB方法。這樣就激活了Authorization提
供程序和Role Mapper,由他們來決定那個Subject是否能訪問它所調用的EJB方法。Role
Mapper的作用是決定Pricipals中保持的Roles是否允許訪問那個方法。如果允許,容器繼續進行方法調用。應該注意的是,在授權過程開始之
前,驗證信息驗證器會驗證傳來的Subject中的驗證信息,看認證之后它有沒有被篡改。

圖4 WLS 7.0的授權機制
基于瀏覽器的客戶端使用與服務器相同的授權機制。區別在于Subject是由Web容器保存在服務器上,還是從客戶端應用程序中傳過來。瀏覽器發送cookie中的會話 ID,Web容器在內部線程中定位subject,然后調用安全框架進行授權。
結論
JAAS是一種認證授權機制,它由JAAS規范定義,在JDK
1.4中實現。JAAS為了實現對認證和授權的檢查,采用了SecurityManager、AccessController、
LoginModule、以及Subject。我們通過Java安全及策略文件配置這些機制,達到保護系統資源和屬性的目的。WebLogic用JAAS
中的LoginModule和Subject進行認證和授權;不過Configuration并不是特指Java的安全和策略文件,也不一定非要從這些文
件中獲取。
Security提供程序可通過WebLogic控制臺進行配置,它在WebLogic服務器上實現了Java中SecurityManager和
AccessController的角色。通過定義WebLogic角色和WebLogic資源之間關聯的安全策略,Security提供程序可以控制對
WebLogic資源的訪問。角色既可以通過控制臺,也可以通過配置描述文件來配置。WebLogic的Authentication提供程序用
LoginModule和Subject建立一個用戶的身份標識。WebLogic的Authorization提供程序通過一個認證Subject,并
基于定義的資源安全策略,以及認證Subject的Principal中保存的角色,賦予或者拒絕對WebLogic資源的訪問。
posted on 2006-10-24 10:41
安文豪 閱讀(1032)
評論(0) 編輯 收藏