JAAS基礎(chǔ)認(rèn)證和授權(quán)機(jī)制
認(rèn)證和授權(quán)是兩種最基本的安全機(jī)制。認(rèn)證就是簡(jiǎn)單地對(duì)一個(gè)實(shí)體的身份進(jìn)行判斷;而授權(quán)則是向?qū)嶓w授予對(duì)數(shù)據(jù)資源和信息訪問權(quán)限的決策過程。JDK 1.4已經(jīng)集成了一項(xiàng)提供認(rèn)證和授權(quán)功能的標(biāo)準(zhǔn)服務(wù),該服務(wù)就稱為Java認(rèn)證和授權(quán)服務(wù)。 JAAS通過一個(gè)配置文件來定義認(rèn)證機(jī)制,而根本不需要使用任何代碼。認(rèn)證機(jī)制之所以需要參數(shù)是為了確定用戶的身份(對(duì)用戶進(jìn)行標(biāo)識(shí))。用來對(duì)用戶進(jìn)行認(rèn)證的參數(shù),例如每種認(rèn)證機(jī)制中使用的用戶名和口令,都稱為驗(yàn)證信息。Subject表示我是的那個(gè)人,但是我們也可以使用驗(yàn)證信息(可以理解為駕駛執(zhí)照)向巡警證明自己的身份,并使用另外一個(gè)驗(yàn)證信息(可以理解為護(hù)照)向邊防警察證明自己的身份。授權(quán)只能在認(rèn)證之后進(jìn)行,因?yàn)樵谙蛴脩糸_放保護(hù)資源的訪問權(quán)限之前,必須對(duì)用戶的身份進(jìn)行確認(rèn)。JAAS框架對(duì)由配置文件指定的認(rèn)證模塊進(jìn)行了包裝。如果認(rèn)證成功,就會(huì)返回一個(gè)包含驗(yàn)證信息的Subject,認(rèn)證機(jī)制所返回的這個(gè)驗(yàn)證信息會(huì)用于授權(quán)過程。 JAAS首先使用一個(gè)LoginContext類來查找配置文件中的內(nèi)容,這些內(nèi)容可以用來對(duì)LoginModules進(jìn)行初始化(見圖1)。所有LoginContext沒有指定的初始化參數(shù)都會(huì)包含在配置文件中。LoginContext還會(huì)向LoginModule傳遞一個(gè)CallbackHandler,CallbackHandler又會(huì)回調(diào)適當(dāng)?shù)膽?yīng)用程序,從而獲得其他認(rèn)證信息。例如,如果LoginContext在創(chuàng)建CallbackHandler時(shí)沒有指定用戶名和口令,而LoginModule又的確需要這些內(nèi)容,那么LoginModule就會(huì)使用CallbackHandler來回調(diào)LoginContext,以重新獲得所需要的信息。 為了讓驗(yàn)證信息可用于登錄,LoginContext還可以向LoginModule傳遞Subject。
WebLogic Application Server(WLS)7.0并沒有對(duì)JAAS進(jìn)行任何修改,JAAS依然是一個(gè)獨(dú)立的擴(kuò)充框架。WLS 7.0包含了自己的認(rèn)證和授權(quán)機(jī)制,它并不需要策略文件。配置文件會(huì)對(duì)WLS LoginModule進(jìn)行定義,使其用來包裝WLS的認(rèn)證機(jī)制。WLS LoginModule通常需要一個(gè)用戶名、一個(gè)口令以及一個(gè)指向適當(dāng)WLS服務(wù)器的URL。WLS 7.0還包含了一種授權(quán)機(jī)制,可以對(duì)映射資源和角色進(jìn)行授權(quán)。由于WLS 7.0在WebLogic的安全框架中實(shí)現(xiàn)了一種授權(quán)機(jī)制,因此策略文件和Java安全管理程序都不需要定義。在調(diào)用PrivilegedAction類時(shí),需要使用weblogic.security.Security類。 WebLogic 7.0給出了一個(gè)例子來展示如何執(zhí)行基于JAAS的認(rèn)證和授權(quán),該例是在一個(gè)Java客戶端應(yīng)用程序中調(diào)用EJB來使用JAAS授權(quán)開放對(duì)資源的訪問限制。這個(gè)例子對(duì)下面Sun的例子稍微進(jìn)行了修改: 這個(gè)例子包括一個(gè)JAAS配置文件,該文件指定了以下內(nèi)容:EJB客戶端用來執(zhí)行認(rèn)證的LoginModule的類名;用來搜集客戶端證書和認(rèn)證服務(wù)器的URL的CallbackHandler;一個(gè)PrivilegedAction類,該類包含了執(zhí)行EJB訪問操作的代碼;以及一個(gè)客戶端應(yīng)用程序,該程序會(huì)創(chuàng)建一個(gè)LoginContext,調(diào)用login( )方法,并通過weblogic.security.Security.runAs方法來調(diào)用PrivilegedAction類。這個(gè)例子的流程如圖3所示。你可以查看/weblogic700/samples/server/src/examples/security/jaas文件來參考完整的例子。本文后面的內(nèi)容會(huì)參考這個(gè)例子,從遠(yuǎn)程客戶端的角度來討論WLS中基于JAAS的認(rèn)證和授權(quán),并將其與服務(wù)器端的組件(例如servlet)進(jìn)行比較。
Sample { UsernamePasswordLogin- Module的代碼沒有包含在示例包中,不過類文件位于weblogic.jar中。代碼的詳細(xì)內(nèi)容見http://edocs./wls/docs70/security/cli_apps.html#1096287。 它使用weblogic.security.auth.Authenticate類(WebLogic專用的類)來對(duì)通過URLCallback指定給LoginModule的實(shí)例進(jìn)行認(rèn)證。該應(yīng)用程序的CallbackHandler提供了服務(wù)器的URL,服務(wù)器通過自己已配置的Authentication Provider進(jìn)行認(rèn)證。 LoginModule會(huì)向CallbackHandler傳遞NameCallback和PasswordCallback來獲得客戶端的用戶名和口令,其中該客戶端開始了應(yīng)用程序。一旦用戶通過認(rèn)證,LoginContext就會(huì)將Subject傳遞給LoginModule。然后,應(yīng)用程序使用LoginContext.getSubject方法獲得認(rèn)證過的Subject。Subject中包含了WebLogic 驗(yàn)證信息--它可以是一個(gè)WLSUser,也可以是一個(gè)WLSGroup--它會(huì)在把Subject傳遞給Security.runAs方法時(shí)用來進(jìn)行認(rèn)證。整個(gè)JAAS認(rèn)證過程是由應(yīng)用程序在實(shí)例化LoginContext類并調(diào)用LoginContext.login( )方法時(shí)進(jìn)行初始化的。LoginContext會(huì)尋找一個(gè)已經(jīng)裝載了在JAAS策略文件中發(fā)現(xiàn)的信息的Configuration對(duì)象。它使用Configuration來創(chuàng)建一個(gè)LoginModule的實(shí)例,該實(shí)例會(huì)用于此后的認(rèn)證過程。 // Create LoginContext; specify username/password login module 這個(gè)LoginContext的實(shí)例化過程會(huì)定位一個(gè)在Configuration中找到的LoginModule并對(duì)其進(jìn)行實(shí)例化,它使用"Sample"名字在Configuration中查找LoginModule,并將SampleCallbackHandler傳遞給它的初始化方法。從sample_jaas.config文件的內(nèi)容中,你可以看到LoginContext會(huì)對(duì)一個(gè)UsernamePasswordLoginModule的實(shí)例進(jìn)行實(shí)例化,從而進(jìn)行認(rèn)證。 根據(jù)WebLogic文檔,在WLS 7.0版本中并不推薦使用weblogic.jndi.Environment類。然而,該例子中提供的LoginModule使用weblogic.jndi.Environment對(duì)象,通過向Authenticate.authenticate方法傳遞Environment來執(zhí)行認(rèn)證。其中Environment中包括用戶名、口令以及服務(wù)器的URL。這是一個(gè)很明顯的矛盾,因此我們還要在其中加入LoginModule的可插入特性這一優(yōu)點(diǎn)。示例LoginModule的機(jī)制,也就是Authenticate類的用法,對(duì)于客戶端應(yīng)用程序自己試圖向WebLogic服務(wù)器進(jìn)行認(rèn)證時(shí)是不可見的。由于LoginModule是可插入認(rèn)證模塊(Pluggable Authentication Module,PAM)的一個(gè)實(shí)例,因此它可以方便地進(jìn)行替換或重寫,而不會(huì)影響到客戶端的應(yīng)用程序。這是展示LoginModule可插入特性是如何防止開發(fā)脆弱的應(yīng)用程序代碼的一個(gè)很好的例子。 Authenticate.authenticate方法會(huì)連接到在URL中指定的WebLogic服務(wù)器上,并可以向服務(wù)器傳遞Subject或Environmet(其中包含了證書),從而由為服務(wù)器的WebLogic安全區(qū)域配置的Authentication提供程序進(jìn)行認(rèn)證。服務(wù)器的安全成員域中配置的Authentication提供程序也實(shí)現(xiàn)了LoginModule。Authentication提供程序的實(shí)現(xiàn)可以使用各種技術(shù)實(shí)現(xiàn)認(rèn)證,例如LDAP或關(guān)系數(shù)據(jù)庫(kù)。如果認(rèn)證成功,Authentication提供程序就向Subject中增加認(rèn)證過的Principal。在將驗(yàn)證信息加入Subject之前,它會(huì)向驗(yàn)證信息驗(yàn)證器發(fā)起一個(gè)請(qǐng)求,從而對(duì)驗(yàn)證信息進(jìn)行數(shù)字簽名。這樣,在調(diào)用Security.runAs返回Subject并試圖執(zhí)行關(guān)鍵授權(quán)檢查時(shí),可以防止惡意的客戶端篡改所返回的Subject中嵌入的驗(yàn)證信息。驗(yàn)證信息驗(yàn)證器會(huì)在授權(quán)過程中進(jìn)行查詢,從而確保所返回的Subject和在認(rèn)證過程中進(jìn)行數(shù)字簽名過的Subject完全相同。 基于瀏覽器的認(rèn)證 當(dāng)我們使用其中一個(gè)方法對(duì)Web客戶端進(jìn)行認(rèn)證時(shí),Web容器根據(jù)客戶端的行為調(diào)用Web安全框架,并訪問Authentication 提供程序。這種機(jī)制的結(jié)果是生成了一個(gè)JAAS Subject,其中包含一個(gè)經(jīng)過認(rèn)證的驗(yàn)證信息,保存在一個(gè)內(nèi)部會(huì)話對(duì)象之中。從該客戶端發(fā)來的后續(xù)請(qǐng)求通過HttpRequest中傳來的cookie中的會(huì)話ID,就可以在內(nèi)部會(huì)話中定位這個(gè)Subject,從而完成授權(quán)。此處的要點(diǎn)在于,WebLogic上的資源容器,像Web容器,也要使用基于JAAS的認(rèn)證,根據(jù)Web客戶端的行為,調(diào)用Authentication提供程序,獲取一個(gè)填充有經(jīng)過認(rèn)證的驗(yàn)證信息的Subject。Authentication提供程序使用的LoginModule并沒有在JAAS配置文件中配置,這一點(diǎn)與Java客戶端的例子不同。通過管理控制臺(tái)將Authentication提供程序增加到活動(dòng)的安全成員域中,就可以實(shí)現(xiàn)對(duì)Authentication提供程序的配置。WLS 7.0 默認(rèn)配置的Authentication提供程序和LoginModul都是即裝即用的,使用了一個(gè)內(nèi)嵌的LDAP服務(wù)器。服務(wù)器端用來認(rèn)證基于Web的客戶端的LoginModule就是Java客戶端應(yīng)用程序的UsernamePasswordLoginModule調(diào)用Authenticate.authenticate方法傳遞Subject和Environment對(duì)象進(jìn)行認(rèn)證時(shí)使用的那個(gè)LoginModule。這個(gè)Subject沒有傳回Web客戶端,而是由Web容器保存在內(nèi)部會(huì)話對(duì)象中,稍后通過會(huì)話ID訪問。 基于JAAS的授權(quán)盡管WLS中的授權(quán)沒有使用JAAS的Subject.doAs方法,它仍然是基于JAAS Subject的。要求訪問受保護(hù)的WebLogic資源的應(yīng)用程序通過weblogic.security.Security.runAs方法請(qǐng)求訪問。Subject和PrivilegedAction被傳遞給這個(gè)WLS安全框架方法,以執(zhí)行有關(guān)一項(xiàng)WebLogic資源的任務(wù)。 WebLogic資源 通過Jave安全策略文件中的安全策略,我們可以對(duì)Java系統(tǒng)資源進(jìn)行保護(hù),而WebLogic的資源與此不同,對(duì)這些資源的保護(hù)是通過將WebLogic角色與WebLogic資源關(guān)聯(lián)起來的安全策略進(jìn)行的。一項(xiàng)WebLogic資源定義為一個(gè)結(jié)構(gòu)化的對(duì)象,表示服務(wù)器端實(shí)體,可以保護(hù)這些實(shí)體拒絕未經(jīng)授權(quán)的用戶進(jìn)行訪問。WebLogic資源的例子有:EJB方法、servlet以及JMS Destination。有關(guān)更多可以用WebLogic角色保護(hù)的WebLogic資源類型實(shí)例,請(qǐng)參看http://edocs./wls/docs70/dvspisec/atz.html#1134702處的文檔, WebLogic角色 WebLogic角色的概念是在WLS 7.0中建立的,它代替了以前發(fā)布的WebLogic中基于ACL的授權(quán)。根據(jù)WLS的文檔,一個(gè)角色定義為一個(gè)抽象的邏輯用戶集合,與組的概念類似。但是角色與組不一樣,因?yàn)榻巧歉鶕?jù)用戶名、組成員以及時(shí)間動(dòng)態(tài)更改的。角色與資源一起用,可以創(chuàng)建WebLogic安全策略?;贘AAS的安全策略在Java安全策略文件中定義,其作用是授權(quán)允許訪問codebase、簽名以及驗(yàn)證信息的權(quán)限。將WebLogic角色與WebLogic資源關(guān)聯(lián)在一起,就建立了一個(gè)WebLogic安全策略。WebLogic在應(yīng)用安全策略時(shí)并不會(huì)考慮Java的策略文件。只要當(dāng)決定對(duì)某項(xiàng)資源的訪問權(quán)限時(shí),一個(gè)用戶在這項(xiàng)資源的安全策略定義的角色中,那么這個(gè)用戶就可以訪問這項(xiàng)資源。 WebLogic角色可以是全局的,即可以將角色與所有的WebLogic資源關(guān)聯(lián);也可以是局部的,即與特定的WebLogic資源關(guān)聯(lián)。全局角色通過管理控制臺(tái)定義。安全策略是用局部角色,通過部署描述文件為Web應(yīng)用程序和EJB動(dòng)態(tài)創(chuàng)建的。對(duì)于Web應(yīng)用程序組件,這些角色的聲明及與資源的關(guān)聯(lián)是在web.xml文件;而對(duì)于EJB,則是ejb-jar.xml文件的 WebLogic授權(quán) 當(dāng)應(yīng)用程序通過調(diào)用Security.runAs方法執(zhí)行PrivilegedAction時(shí),Java客戶端應(yīng)用程序的授權(quán)過程就開始了(見圖4)。當(dāng)調(diào)用這個(gè)方法時(shí),應(yīng)用程序?qū)⒄J(rèn)證過的Subject和PrivilegedAction傳遞給WebLogic安全框架。在WLS中,PrivilegedAction內(nèi)部激活了一個(gè)EJB方法,SampleAction.java,調(diào)用的身份標(biāo)識(shí)就是已經(jīng)通過認(rèn)證的Subject。服務(wù)器上的EJB容器從PrivilegedAction的上下文中的客戶端EJB stub對(duì)象那里接收到請(qǐng)求。然后調(diào)用服務(wù)器上的安全框架,確定是否允許該Subject訪問這個(gè)EJB方法。這樣就激活了Authorization提供程序和Role Mapper,由他們來決定那個(gè)Subject是否能訪問它所調(diào)用的EJB方法。Role Mapper的作用是決定Pricipals中保持的Roles是否允許訪問那個(gè)方法。如果允許,容器繼續(xù)進(jìn)行方法調(diào)用。應(yīng)該注意的是,在授權(quán)過程開始之前,驗(yàn)證信息驗(yàn)證器會(huì)驗(yàn)證傳來的Subject中的驗(yàn)證信息,看認(rèn)證之后它有沒有被篡改。
基于瀏覽器的客戶端使用與服務(wù)器相同的授權(quán)機(jī)制。區(qū)別在于Subject是由Web容器保存在服務(wù)器上,還是從客戶端應(yīng)用程序中傳過來。瀏覽器發(fā)送cookie中的會(huì)話 ID,Web容器在內(nèi)部線程中定位subject,然后調(diào)用安全框架進(jìn)行授權(quán)。
JAAS是一種認(rèn)證授權(quán)機(jī)制,它由JAAS規(guī)范定義,在JDK 1.4中實(shí)現(xiàn)。JAAS為了實(shí)現(xiàn)對(duì)認(rèn)證和授權(quán)的檢查,采用了SecurityManager、AccessController、LoginModule、以及Subject。我們通過Java安全及策略文件配置這些機(jī)制,達(dá)到保護(hù)系統(tǒng)資源和屬性的目的。WebLogic用JAAS中的LoginModule和Subject進(jìn)行認(rèn)證和授權(quán);不過Configuration并不是特指Java的安全和策略文件,也不一定非要從這些文件中獲取。 Security提供程序可通過WebLogic控制臺(tái)進(jìn)行配置,它在WebLogic服務(wù)器上實(shí)現(xiàn)了Java中SecurityManager和AccessController的角色。通過定義WebLogic角色和WebLogic資源之間關(guān)聯(lián)的安全策略,Security提供程序可以控制對(duì)WebLogic資源的訪問。角色既可以通過控制臺(tái),也可以通過配置描述文件來配置。WebLogic的Authentication提供程序用LoginModule和Subject建立一個(gè)用戶的身份標(biāo)識(shí)。WebLogic的Authorization提供程序通過一個(gè)認(rèn)證Subject,并基于定義的資源安全策略,以及認(rèn)證Subject的Principal中保存的角色,賦予或者拒絕對(duì)WebLogic資源的訪問。
|
|||||||||
|
|