1 引言
隨著電子商務和電子政務系統(tǒng)的普及,越來越多的公司或機構面臨著同樣的尷尬,公司內運行著多套系統(tǒng),,每個系統(tǒng)都是一個孤島,有自己的認證和訪問策略,。對用戶來說,各系統(tǒng)都需要輸入用戶名,,密碼,,不僅麻煩,而且降低了系統(tǒng)的安全性,。為解決這對矛盾,,產生了單點登錄(Single Sign On,SSO[1,,2])的概念,。所謂單點登錄的核心思想是通過一定的方式使得提供服務的各網站之間建立某種聯(lián)系,提供了允許用戶只需一次登錄到站點的內建機制或者上下文環(huán)境,,在登陸相互聯(lián)系的多個網站時只需要進行一次驗證即可,,從而保持了應用外觀的無縫性,對用戶的透明性,。
2 傳統(tǒng)認證方法比較
單點登錄系統(tǒng)的核心模塊就是其訪問控制模塊,,不同的實現(xiàn)方案,采取的策略不同或者基于不同的安全標準,。有的基于Kerberos[3]認證協(xié)議,,有的利用windows NT的LDAP(Lightweight Directory Access Protocol),也有的基于Solaris NIS網絡信息服務的認證,。雖然有不少產品是利用java開發(fā)的,,但無論Servlet還是EJB的規(guī)范都沒有明確定義如何來實現(xiàn)SSO,即使在授權方面,,也沒有明確的解決方案,。我們可以在J2EE的藍皮書中看到對于同一個例子:Java Pet Store的訪問控制的幾個不同的解決方案,各有其優(yōu)缺點,。
在1.0.1版本中,,使用基于表單的認證方式,這是我們在web或者電子商務開發(fā)中常用的方式,。當用戶到達一個不被授權訪問的資源時,,web容器就推出一個html頁面,要求輸入用戶名和密碼,,其缺點就是:可移植性差[6],。
在1.1.2版本中,采用了基于Servlet的架構,,基于Servlet的Sign in/Sign out來集中處理所有的request請求,,來代替form-based架構的訪問控制,這樣可以使訪問控制模塊的代碼移植到所有支持J2EE平臺的應用上,而無需修改代碼,。缺點是必須由應用程序自己來處理,。
在版本1.3中 ,采用了Filter來實現(xiàn),。利用Filter來阻止未授權的訪問,。在這種方案中,F(xiàn)ilter過濾所有的HTTP請求和響應,。如成功登錄,,在用戶的session中,設置一個標記,,F(xiàn)ilter在每次響應前檢查該標記是否為真,。因為過濾所有的HTTP請求和響應,導致響應不及時,,增加了響應時延,。
如果我們想開發(fā)一個可重復利用的、移植性好的SSO模塊,,以上的三種方案,,都不可行。本文利用在J2SE 1.4及以后的版本中推出的JAAS[4](Java Authentication Authorization Service)可以很好的解決這個問題,。
3 JAAS概述
3.1 JAAS概述
JAAS在J2SE 1.3版本中還是一個可選的包,,現(xiàn)在已經集成到J2SE 1.4版本中,是1.4及以上版本的標準類庫。伴隨著J2SE1.5版本的發(fā)布,,更包含了許多諸如加密技術,、XML安全性、公鑰機制(PKI),、Kerberos和結盟認證(the federating identity)的增強,,JAAS在J2EE實現(xiàn)中扮演一個越來越重要的角色。
JAAS框架是從各種不同的安全框架和技術發(fā)展而來的,,JAAS 的可堆疊和可插接功能基于 Unix 的可插接驗證模塊 (Pluggable Authentication Module, PAM) 框架,。完全遵循 Java Cryptography Architecture(Java 加密體系結構,JCA)框架體系結構,,它允許通過 Service Provider Interface(服務提供接口,,SPI)安插多種安全機制,實現(xiàn)了一個Java版本的可插入式驗證模塊(Pluggable Authentication Module,,PAM),,在實現(xiàn)方面具有獨立性和互操作性,,在算法上具有獨立性和可擴展性,。這就使得上層的應用程序與底層所使用的各種驗證技術保持相對獨立,新的或修改后的驗證技術能夠方便地部署到應用程序而不需要修改應用程序的代碼。同時,,JAAS 還引用了二個階段的提交協(xié)議中的的事務行為和 J2SE 1.2 安全包中的安全配置概念,。因此,JAAS 是多種技術和概念的精華,,它代表了 Java 編程語言的發(fā)展方向,。
JAAS API 包含兩個方面的安全內容,即認證和授權認證是一種通過可靠的方式確定誰是 Java 代碼執(zhí)行者的方法,;而授權是一種確保該人具有執(zhí)行某種給定任務權限的方法,。在本文中,我們結合SSO重點討論JAAS的認證部分,。
3.2 JAAS認證機制
認證就是校驗一個用戶擁有使用已經被企業(yè)用戶注冊機構證明了的身份鑒定的權限的處理過程,。JAAS的認證機制建立于一整套插拔" title="可插拔">可插拔的模塊(參看圖1)基礎上。JAAS允許不同的驗證模型(SUN提供了幾個默認的LoginModule ,,在sun.com.security.auth.module包里有諸如JndiLoginModule,Krb2LoginModule,UnixLoginModule和NTLoginModule等module,,也可以自定義module)在運行時可被插拔??蛻魬每偸峭ㄟ^LoginContext和JAAS交互,。
典型的認證處理過程要經過下面的步驟:
1. 創(chuàng)建登錄環(huán)境,生成一個LoginContext對象,。
LoginContext ctx=new LoginContext(“MyApp”);
LoginContext尋找配置文件以決定使用那個LoginModule,,也有可能傳遞一個回調處理程序對象CallbackHandler給LoginContext以搜集用戶驗證信息如用戶名和口令,作為選擇,。
2.?通過調用LoginContext的login方法執(zhí)行認證,,它會加載預定義的LoginModule去檢驗是否用戶可以被認證。
3.?如果用戶被認證,,那么用規(guī)則和標識和其屬性進行關聯(lián),,?或者在登陸失敗的情況下拋出一個LoginException。
?使用LoginContext的logout方法進行注銷登陸,。
????????????
???????????????????????????????????? 圖1 JAAS的可插拔模塊認證機制概覽圖
在JAAS中,,登陸是一個兩階段(Two-phase)的處理過程。第一階段是login階段(就像上面2所描述的),。這個階段唯一的任務是認證,。只要處理過程成功通過這個階段,認證處理過程就進入了“提交(commit)”階段(如上步驟3),,這一階段LoginModule的commit方法被調用去關聯(lián)所屬子項相關的規(guī)則和標識,。
在所有的認證模塊當中,LoginModule是事實上的認證機制的借口,。雖然LoginModule決沒有得到直接調用客戶應用的機會,,但是他經由一個可插拔的模塊提供了一個認證的具體類型,,其實現(xiàn)了認證的算法并且決定實際的認證過程是怎樣被執(zhí)行的。
JAAS認證結構體系是可擴展的,,所以只要在配置文件中指定使用哪個LoginModule模塊就可以幾乎全部插入任何LoginModule模塊,,如下例所示:
MyApp{
Com.exercise.jaas.module.myLoginModule required debug=ture;
};
這里MyApp是LoginContext的名字,當你生成一個新的LoginContext開始認證過程時它會被傳入LoginContext的構造函數中,。依據配置文件,,提醒JAAS有關LoginModule在登錄過程中應該被用來執(zhí)行認證(此config文件表明myLoginModule將被使用)。
Required參數及其備選參數用于指定一個給定的驗證過程的成功或失敗對總體驗證過程的影響:
1)required表示登錄模塊必須成功,。即使它不成功,,還將調用其它登錄模塊。
2)optional表示登錄模塊可以失敗,,但如果另一個登錄模塊成功,,總體登錄仍可以成功。如果所有登錄模塊都是可選的,,那么要使整個認證成功至少必須有一個模塊是成功的,。
3)requisite表示登錄模塊必須成功,而且如果它失敗,,將不調用其它登錄模塊,。
4)sufficient表示如果登錄模塊成功,則總體登錄將成功,,同時假設沒有其它必需或必不可少的登錄模塊失敗,。
ModuleOption允許有多個參數。例如你可以設定調試參數為True(debug=true),,這樣診斷輸出將被送到System.out中,。
4.單點登錄系統(tǒng)中認證功能的設計和實現(xiàn)
目前已經出現(xiàn)了眾多的商用SSO產品,但一般都價格昂貴,,或者局限于特定的平臺,,例如:Microsoft的.net Passport、IBM WebSphere Portal Server,、Netegrity SiteMinder等,,由于J2EE沒有定義SSO的具體實現(xiàn)方法,他們的實現(xiàn)機制不盡一樣;盡管如此,,但這些產品的實現(xiàn)機制都遵循一種通用的模式,,這種模式由三個主要部分組成:入口檢查單元(Gatekeeper)、身份認證單元(Authenticator),、用戶憑征存儲單元(User Credential Store),,我們稱在這三個部分基礎上的SSO為GAC-SSO[6](GateKeeper,Authenticator and Credential Store SSO),,這三個組成部分之間的交互關系描述如下:
1.當Gatekeeper檢查到用戶請求一個受保護的資源時,,它首先檢查該用戶是否已經為該Web應用創(chuàng)建好一個Login Session,,若沒有,Gatekeeper再檢查是否已經建立一個和Authenticator相關的全局SSO session,;
2.若沒有建立全局的SSO Session,用戶被導向到Authenticator的登錄頁面,,并要求用戶提供用戶名和密碼等憑證信息,;
3.Authenticator接受用戶提供的憑證信息,然后通過用戶的身份認證系統(tǒng)驗證用戶,;
4.若Authenticator驗證成功,,建一個全局Login Session,導向至Gatekeeper,,并在該用戶的Web應用中為其創(chuàng)建一個Login Session,;
5.Authenticator和Gatekeepers之間通過多種方式進行交互,例如:共享cookie方式,、Web Service的SOAP或者利用安全聲明標記語言(SAML)來進行信息的安全交換,。
在GAC-SSO中采用JAAS的認證機制,使得認證變得簡單可行,。由于JAAS支持插拔的認證機制,,可以根據需求進行定制不同的LoginModule,僅對配置文件進行適當的修改,,而代碼幾乎可以不作修改,,如我們采用基于Kerberos協(xié)議的認證機制,SUN已默認實現(xiàn)其LoginModule即Krb2LoginModule,就無需再編碼實現(xiàn)該Module,,極大的節(jié)省了工作量,。
同時,從圖1可以看出,,在LoginModule之間共享用戶驗證信息是利用JAAS實現(xiàn)單點登錄的基礎和關鍵,,在此我們采用JAAS實現(xiàn)。首先把各種認證機制按需放入配置文件的登錄模塊列表中,。在LoginModule接口的initialize(Subject subject,,CallbackHandler callbackhandler,Map sharedState,,Map options)方法中,,Map類型的sharedState參數可用于登錄模塊之間的數據共享,因此可用于共享各驗證過程的登錄狀態(tài),。
在LoginContext類的login()方法中定義Map類型的成員變量sharedStateMap,,在執(zhí)行LoginModule的initialize()方法時會將該對象傳遞給登錄模塊。Map對象可保存兩個對象之間的映射關系,,因此GateKeeper中只要執(zhí)行Map類型的sharedStateMap對象的put(userName,,loginFlag)方法,,即可將需要傳遞的信息loginFlag與userName關聯(lián),來判斷userName是否登錄(其中每個用戶的userName在整個的GAC-SSO中必須唯一),。其他登錄模塊只要使用sharedStateMap對象的get(userName)方法即可獲取該userName的登錄狀態(tài),,擴展開來也可以實現(xiàn)其他共享信息的傳遞,但若系統(tǒng)的權限控制較復雜,,共享信息較多的話,,可以在User Credential Store模塊中,利用Principal對象貯存用戶的身份等共享信息,,通過Principal對象進行傳遞,。據此我們可以開發(fā)出符合要求的單點登錄系統(tǒng)。
5 結束語
GAC-SSO模式比較適合中小企業(yè),,尤其是那些需要建立自己的SSO系統(tǒng),,但又沒有很多初始投資的企業(yè);基于這一模式,,企業(yè)不需要依賴特定的SSO產品,,就可以建立擁有自有技術的單點登錄解決方案。文中介紹了單點登錄的概念和JAAS框架的構成,,最后提出了利用JAAS實現(xiàn)單點登錄的用戶驗證功能,。
參考文獻
[1]. The Open Group's "Introduction to Single Sign-On"[EB/OL], http://www.opengroup.org/security/sso/sso_intro.htm?
[2] Mayank Upadhyay and Ram Marti, Single Sign-On Using Kerberos in Java, [EB/OL] http://java.sun.com/j2se/1.4.2/docs/guide/security/jgss/single-signon.html, May 2 2001
[3] John Kohl and B. Clifford Neuman,The Kerberos Network Authentication Service (Version 5). Internet Request for Comments RFC-1510, September 1993
[4] JAAS Overview[EB/OL], http://java.sun.com/products/jaas/overview.html, 2002
[5]林天峰,,基于JAAS的Java安全編程[J],, 計算機應用與軟件,2003年7月,,P86-88
[6] Jian Zhong and Mike Lehr, US Department of Energy signs on to J2EE [EB/OL] http://www.javaworld.com/javaworld/jw-05-2002/jw-0524-signon-p2.html, May 24, 2002
?