擴展JAAS (轉載)

用戶認證和訪問控制是大多數java應用的重要安全尺度,特別是J2EE應用。Java認證和權限服務(即JAAS),J2SE1.4和1.5的核心API,描繪表達了新的安全標準。其提供了一個可插拔的(pluggable)和富有彈性的(flexible)框架(framework)允許開發者混合不同的安全機制和豐富的已經存在各種安全方面的資源。
  伴隨着即將來臨的J2SE1.5版本的發佈,它包含了許多諸如加密技術、XML安全性、公鑰機制(PKI)、Kerberos (是一個網絡附加系統/協議,可以允許用戶通過一個安全伺服器的服務來驗證 自己。象遠端登陸,遠端拷貝,系統間的相互檔拷貝和另外高風險任務的服務將被變 得相當安全和可控制。)和結盟認證(the federating identity)的增強!,JAAS將會在J2EE實現中扮演一個更加重要的角色。
  
  認證
  認證就是校驗一個用戶擁有使用已經被企業用戶註冊機構證明了的身份鑑定的權限的處理過程。JAAS的認證機制建立於一整套可插拔的模塊(參看圖1)基礎上。JAAS允許不同的驗證模型在運行時可被插拔。客戶應用總是通過登陸上下文對象和JAAS交互。
  認證處理過程典型的要經過下面的步驟:
  1、 生成一個LoginContext對象。這個LoginContext尋找配置文件以決定使用那個LoginModule。同樣,可選擇的,有可能傳遞一個CallbackHandler給LoginContext.
  2、 通過調用LoginContext的login方法執行認證,它會加載預定義的LoginModule去檢驗是否用戶可以被認證。
  3、 如果用戶被認證,那麼用規則和標識和其所屬項進行關聯。
  4、 或者在登陸失敗的情況下跑出一個LoginException
  5、 使用LoginContext的logout方法進行註銷登陸
  
  在JAAS中,登陸是一個兩階段(two-phase)的處理過程。第一階段是“登陸(login)”階段(就像上面2所描述的)。這個階段唯一的任務是認證。只要處理過程成功通過這個階段,認證處理過程就進入了“提交(commit)”階段(如上步驟3),這一階段LoginModule的commit方法被調用去關聯所屬子項相關的規則和標識。
  在JAAS中一個所屬子項表示一個認證實體,比如一個人或者一臺設備。它包含了一整套法則和安全相關的屬性諸如密碼和加密密鑰。在JAAS體系結構中,所屬子項和其所附屬的相關權限,扮演了重要的角色在認證過程當中。所有的認證模塊當中,LoginModule是事實上的認證機制的藉口。雖然LoginModule決沒有得到直接調用客戶應用的機會,但是他經由一個可插拔的模塊提供了一個認證的具體類型,其實現了認證的算法並且決定實際的認證過程是怎樣被執行的。
  SUN提供了幾個默認的LoginModule 實現,在sun.com.security.auth.module包裏有諸如JndiLoginModule,Krb2LoginModule,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應用環境的系統安全策略和在任何時間事實上只有一個策略對象。依據Java2 SDK文檔,默認的策略實現是sun.security.provider.PolicyFile,其中策略被指定在一個或多個策略配置文件裏。
  只要用戶被認證,授權經由Subject.doAs方法發生,或者從Subject類的靜態方法doAsPrivileged,doAS方法用當前的AccessControlContext動態和子項並且同時調用run方法去執行動作,他導致安全驗證。權限驗證過程通過下面的步驟在圖2:
  就像LoginModule,策略也是可插拔的模型。你可以掛上其它的策略實現通過在java.security的屬性文件中改變“policy.provider=sun.security.provider.PolicyFile”
  到一個你項使用的策略類。
  
  Extend JAAS
  JAAS建立於已經存在的Java安全模型的頂端,其基於“CodeSource”和平面文本格式策略文件實現。這可能對企業應用是不夠用的,你可能想使用可定製的安全倉庫。對於JAAS的其它實現,諸如LDAP(輕型目錄訪問協議),數據庫或者其他文件系統,它可以通過編寫你自己的可定製模塊被完成,感謝JAAS的可插拔的特性。然而,這需要對模塊和JAAS中的處理過程有完善的理解,同時你必須做許多編碼去覆寫相關的類,並且處理好配置和策略兩種文件。
  理想情況下,我們願意能夠擴展JAAS以一個更加容易的方式以便於無論何時一個可定製的安全知識庫或者不同的訪問控制機制改變或者必須去增加時,你能夠只開發和插入這些不同的小模塊(即,適配器)去適應這些新的變化和需求,並且在最好的情況下,不必去理解和熟悉JAAS處理過程的細節,同樣,我們也願意能夠去做這些變化僅僅通過改變一個配置文件。另一個目標是我們的JAAS擴展組件能夠被使用在不同的J2EE應用中—獨立的或者Web上的。圖3描述了JAAS擴展組件的設計意圖。我們的JAAS擴展組在實現可定製的LoginModule和策略模塊時充分件利用了JAAS插拔式的體系結構。這些模塊中,我們委派數據請求到適配器。這些適配器的每個對於諸如數據取回的簡單任務是隔離的,所以你可以快速地使用不同的安全知識或者算法開發不同的適配器而不是嘗試去實現不同的LoginModule或者策略模塊,它們更加複雜並且需要更多的努力。
  你可以從www.sys-con.com/java/sourcec.cfm.下在完整的源瑪。
  
  實現的AuthLoginModule類
  AuthLoginModule類是我們定製的LoginModule實現,LoginModule類是在JAAS中是一個可插拔組件並且服務於兩個目的:
  1、鑑定認證用戶
  2、如果認證成公,則用相關的負責人信息或者證書更新主題。
  
  LoginModule有5個方法去實現功能,讓我們關注一下login()方法。這個方法被調用以認證主題並且主要作兩件事情:
  1、包含用戶名和密碼,典型地,LoginModule要調用CallbackHandler類的handle方法去得到用戶名和密碼
  2、通過和數據源中的比較校驗密碼。LoginModule從Callbacks取回用戶名和密碼。(其默認期望用戶接口的某種排序),這一點對於一個簡單的演示程序或者就在命令行,可是他對於一個J2EE應用來說不太實用,例如,對於大多數的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類是一個認證目的的資源適配器的接口,它有4個需要實現的方法:
  1、void initialize(Hashtable parameters):initialized方法被調用來以相關的參數初始化適配器。此方法在對象生成後立即被調用並且優先於任何對其他方法的調用。
  2、boolean authenticate(String username,char[] password):此認證方法被調用來認證用戶。
  3. String[] getGroupNames (String userName):getGroupNames方法被調用來在認證成功後得到相關的主要信息。
  4. void terminate ():這個方法在LoginModule類的logout方法被執行後調用,它給適配器做一些清理工作的機會。
發佈了16 篇原創文章 · 獲贊 0 · 訪問量 1939
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章