標籤:des http java 使用 strong width
一.簡介
現在越來越多的公司專屬應用程式構建在j2ee平台上,這得益於j2ee為公司專屬應用程式的開發提供了良好的架構和服務的支援.j2ee為公司專屬應用程式提供了多方面的服務(Security、Transaction、Naming等).本文將介紹j2ee提供的安全服務.作者首先介紹j2ee中的安全概念和j2ee的安全體系架構.然後結合具體的執行個體向讀者展示如何在自己的程式中應用j2ee提供的安全特性。本文所介紹的內容是基於j2ee1.3版本的。
二.j2ee中的安全概念
主體(Principal):主體(Principal)是被在企業安全服務驗證了的實體。主體(Principal)用主體名作為它的標識,通過與主體相關的驗證資料進行驗證。通常情況下主體名就是使用者的登陸名,驗證資料就是登陸的密碼。J2EE規範中並沒有限定J2EE 產品供應商使用怎樣的認證方法,因此主體名和驗證資料的內容和格式依不同的認證協議而不同。
安全性原則域(Security Policy Domain):也稱安全域(security domain)或 realm,它是一個邏輯範圍或地區,在這一範圍或地區中安全服務的管理員定義和實施通用的安全性原則。它是從安全性原則的角度劃分的地區。比如可以將公司專屬應用程式系統劃分為企業員工、供應商、夥伴等不同的安全域,對這些安全區域採用不同的安全性原則。
安全技術域(Security Technology Domain):它是從安全技術的角度劃分的地區,在一個安全技術域中使用同樣的安全機制來執行安全性原則。一個安全技術域可以包括多個安全性原則域。
安全屬性(Security Attributes):每個主體(Principal)都有一系列與之相關的安全屬性。安全屬性可用來訪問被保護的資源,檢查使用者的身份和完成其他一些安全相關的用途。J2EE產品供應商或具體的驗證服務的實現來決定怎樣將安全屬性與一個主體聯絡起來。J2EE規範並沒有限定什麼樣的安全屬性將與主體相聯絡。
憑證(Credential):憑證包含或引用為J2EE 系統驗證一個主體的驗證資訊(安全屬性)。如果成功的通過了驗證,主體將獲得一個包括安全屬性的憑證。如果被允許的話,一個主體也可能擷取另一個主體的憑證。在這種情況下兩個主體在同一安全域中具有相同的安全屬性。
三.j2ee的安全體繫結構1. 基於容器的安全
在j2ee的環境中,組件的安全是由他們各自的容器來負責的,組件的開發人員幾乎可以不用或者很少在組件中添加有關安全的代碼。這種安全邏輯和商務邏輯相對獨立的架構,使得企業級應用系統有更好的靈活性和擴充性。J2ee規範要求j2ee 產品必須為應用程式開發人員提供兩種形式的基於容器的安全性-說明性的安全性和可程式化的安全性。
a. 說明性的安全性
說明性的安全性通過安全結構描述的方式來代表應用程式的安全需求,安全結構一般包括資訊安全角色,存取控制和驗證要求等。在j2ee平台中部署描述符充當了說明的安全性的主要工具。部署描述符是組件開發人員和應用程式部署者或應用程式組裝者之間的交流工具。應用程式的開發人員用它來表示應用中的安全需求,應用程式部署者或應用程式組裝者將資訊安全角色與部署環境中的使用者和組映射起來。
在程式運行時容器從部署描述符中提取出相應的安全性原則,然後容器根據安全性原則執行安全驗證。說明的安全性不需要開發人員編寫任何安全相關的代碼,一切都是通過配置部署描述符來完成的。
b. 可程式化的安全性
可程式化的安全性在說明性的安全性的基礎上,使安全敏感的應用可以通過調用被容器提供的API來對安全作出決斷。這在說明性的安全性不足以滿足企業的安全模型的情況是非常有用的。J2ee在EJB EjbConext interface和servlet HttpServletRequest interface中各提供兩個方法:
isCallerInRole (EJBContext)getCallerPrincipal (EJBContext)isUserInRole (HttpServletRequest)getUserPrincipal (HttpServletRequest)
這些方法允許組件根據調用者或遠端使用者的資訊安全角色來作出商業判斷。在文章的後面部分將有這些方法的詳細介紹和常式,以便讀者更好的理解可程式化的安全性的用途。
2.J2ee的驗證模型
身分識別驗證是使用者或組件調用者向系統證明其身份的過程。使用者通過某種方式向系統提交驗證資訊(通常是使用者名稱和密碼或者是使用者的數位憑證),系統用使用者提供的驗證資訊和系統的安全性原則來驗證使用者的身份。
圖一 初始驗證過程
圖一 初始驗證過程
圖二 驗證URL
圖三 驗證EJB方法調用
使用者的驗證
使用者的驗證根據其用戶端類型不同分為兩種:網頁用戶端的驗證和Application用戶端的驗證
a. 網頁用戶端的驗證
Web用戶端通常通過http協議來請求web伺服器端的資源,這些web資源通常包括html網頁、jsp(java server page)檔案、java servlet和其他一些二進位或多媒體檔案。在企業環境中,企業的某些資源往往要求只允許某些人訪問,有些資源甚至是機密的或安全敏感的。因此對企業中各種web資源進行存取控制是十分必要的。為了滿足企業中的不同安全層級和客戶化的需求,j2ee提供了三種基於web用戶端的驗證方式:
HTTP基本驗證(HTTP Basic Authentication)
HTTP基本驗證 是HTTP協議所支援的驗證機制。這種驗證機制使用使用者的使用者名稱和密碼作為驗證資訊。Web用戶端從使用者擷取使用者名稱和密碼,然後傳遞他們給web伺服器,web伺服器在指定的地區(realm)中驗證使用者。但需要注意的是,這種驗證方法是不夠安全的。因為這種驗證方法並不對使用者密碼進行加密,而只是對密碼進行基本的base64的編碼。而且目標web伺服器對使用者來說也是非驗證過的。不能保證使用者訪問到的web伺服器就是使用者希望訪問的。可以採用一些安全措施來克服這個弱點。例如在傳輸層上應用SSL或者在網路層上使用IPSEC或VPN技術。
基於表單的驗證(Form-Based Authentication)
基於表單的驗證 使系統開發人員可以自訂使用者的登陸頁面和報錯頁面。這種驗證方法與基本HTTP的驗證方法的唯一區別就在於它可以根據使用者的要求制定登陸和出錯頁面。基於表單的驗證方法同樣具有與基本HTTP驗證類似的不安全的弱點。使用者在表單中填寫使用者名稱和密碼,而後密碼以明文形式在網路中傳遞,如果在網路的某一節點將此驗證請求截獲,在經過反編碼很容易就可以擷取使用者的密碼。因此在使用基本HTTP的驗證方式和基於表單的驗證方法時,一定確定這兩種方式的弱點對你的應用是可接受的。
基於用戶端認證的驗證(Client-Certificate Authentication)
基於用戶端認證的驗證方式要比上面兩種方式更安全。它通過HTTPS(HTTP over SSL)來保證驗證的安全性。安全套接層(Secure Sockets Layer)為驗證過程提供了資料加密,伺服器端認證,資訊真實性等方面的安全保證。在此驗證方式中,用戶端必須提供一個密鑰憑證,你可以把這個密鑰憑證看作是你的數字護照。密鑰憑證也稱數位憑證,它是被稱作認證授權機構(CA)-一個被信任的組織頒發的。這個數位憑證必須符合X509公開金鑰體繫結構(PKI)的標準。如果你指定了這種驗證方式,Web伺服器將使用用戶端提供的數位憑證來驗證使用者的身份。
b. 應用程式用戶端的驗證(Application Client User Authentication)
java用戶端程式是執行在使用者本地java虛擬機器上的java程式,它擁有main方法,通常由使用者可通過java.exe或javaw.exe直接啟動執行。J2ee應用程式用戶端與java用戶端程式相似,也擁有main方法,但他們在運行時存在一定的差別。J2ee應用程式用戶端和其他j2ee組件一樣運行在自己的容器中。使用者通過容器來執行J2ee應用程式用戶端。這樣J2ee應用程式用戶端容器就有機會在J2ee應用程式用戶端被執行之前完成使用者身份的驗證。J2ee提供了一種可自訂的方式來擷取使用者的驗證資訊。可以選擇使用容器提供的預設的方式來擷取j2ee應用用戶端程式的使用者的驗證資訊,也可以選擇自訂的方式來擷取使用者的驗證資訊。當選擇自訂方式時,應用程式開發人員必須提供一個實現了javax.security.auth.callback.CallbackHandler interfce的類,並且在j2ee部署描述檔案application-client.xml中的元素callback-handler中加入這個類的類名。這樣,當系統需要驗證使用者身份時,用戶端程式的容器將部署描述檔案中的CallbackHandler實作類別的類名傳遞給系統的登陸模組(驗證模組),登陸模組再執行個體化這個實作類別。這個類的執行個體負責收集使用者驗證資訊,並將收集到的使用者驗證資訊傳遞給登陸模組,登陸模組用這些驗證資訊來驗證使用者。這個實作類別可以是具有使用者介面的,或是通過要求使用者輸入來收集使用者驗證資訊,也可以是通過命令列來擷取使用者驗證資訊,還可能是通過讀取本地或線上的使用者認證庫來擷取使用者的電子認證。選取哪種方式取決於驗證資訊的儲存方式。
有些j2ee產品廠商把容器的驗證服務和本地系統的驗證服務或其他應用系統產品的驗證服務整合起來,從而在一定的應用系統的範圍內實現單點登陸的能力。
單點登陸 (Single Sign-On)
單點登從使用者的視角是指使用者在特定的邏輯安全區域中,只需進行一次登陸即可在訪問在此邏輯安全區域中不同應用系統中的被授權的資源,只有超越了安全區域邊緣時才要求再次登陸。這種能力對多種IT應用系統共存的企業顯得尤為有價值。隨著公司資訊化建設程度的不斷提高,企業中的應用系統也越來越多。在傳統的應用系統中,各系統各自維護自己的安全性原則,這些安全性原則典型的包括組織圖定義,資訊安全角色定義,使用者身分識別驗證,資源存取控制等。由於各系統互相獨立,一個使用者在使用每一應用系統之前,都必須按照相應的系統身份進行系統登陸。這對於使用者來說必須記住每一個系統的使用者名稱和密碼,給使用者帶來了不小的麻煩。針對於這種情況,單點登陸的概念隨之產生,並不斷的應用到企業的應用系統的整合當中。J2ee1.3也在規範中建議j2ee產品應為應用系統提供單點登陸的能力。但j2ee1.3規範並沒有規定j2ee產品應遵循何種標準,因此不同的廠商的產品在單點登陸上的實現和應用各不相同。有的j2ee產品實現了在本產品環境範圍內的單點登陸,有的實現了特定系統內容之間的單點登陸(如IBM WebSphere Application 4.0 AE 實現了WebSphere Application Server與WebSphere Application Server、WebSphere Application Server與Lotus Domino server、WebSphere Application Server與Lotus Domino server之間的單點登陸能力)。在j2ee中單點登陸是通過傳遞憑證(Credential)來實現的.當使用者進行系統登陸時,用戶端容器(包括WEB用戶端和應用程式用戶端)根據使用者的憑證(Credential)為使用者建立一個安全上下文(security Context),安全上下文包含用於驗證使用者的安全資訊,系統用這個安全上下文和安全性原則來判斷使用者是否有訪問系統資源的許可權。遺憾的時j2ee規範並沒有規定安全內容相關的格式,因此不能在不同廠商的j2ee產品之間傳遞安全上下文。到目前為止還很少有在不同的j2ee產品間互相共用安全上下文,因此在不同j2ee產品間實現單點登陸只能通過第三方產品(如LDAP server等)整合的方式。
惰性驗證(Lazy Authentication)
身份驗是有代價的。例如,一次驗證過程也許包括多次通過網路資訊交換。因此惰性驗證就非常有用了。惰性驗證使當使用者訪問受保護的資源時才執行驗證過程,而不是在使用者第一次發起請求時就執行驗證過程。
3. J2ee的授權模型
代碼授權(Code Authorization)
j2ee產品通過java 2 安全模型來限制特定J2SE的類和方法的執行,以保護和確保作業系統的安全。詳細描述請參閱《J2SE規範文檔》。
調用者授權(Caller Authorization)
資訊安全角色:資訊安全角色是具有相同安全屬性的邏輯組。它由應用程式的裝配者(Application Assembler)或應用程式的部署者(Application Deployer)分配的。
資訊安全角色引用:資訊安全角色引用是應用程式提供者(Application Provider)用來引用資訊安全角色的標識。應用程式提供者(Application Provider)可以用資訊安全角色引用來為資訊安全角色分配資源訪問的許可權。也在安全相關的程式碼中引用資訊安全角色。
使用者和組:使用者和組是在實際系統內容下的使用者和使用者的集合。它們對應者現實當中的人和群體。
存取控制:存取控制可以確保資訊安全角色只能訪問已授予它安全許可權的授權對象。授權對象包括EJB的遠程方法、web資源(html網頁,jsp/servlet和多媒體或二進位檔案)等。在j2ee中存取控制在應用程式描述檔案中與資訊安全角色關聯起來。
映射:通過映射應用程式的系統管理員將實際系統內容中的使用者和角色與資訊安全角色聯絡起來,從而是實際的使用者擁有對企業資源訪問的適當授權。
被傳播的調用者身份標識(Propagated Caller Identities)
在j2ee 1.3中可以選擇用傳播調用者標識作為web組件和ejb組件調用者的標識來進行驗證。在這種方式下,整個ejb組件的調用鏈中interface EJBContext的方法getCallerPrincipal返回相同的主體名(principal name)。如果調用鏈中的第一個ejb是被jsp/servlet調用的,interface EJBContext的方法getCallerPrincipal返回的主體名(principal name)應與interface HttpServletRequest的方法getUserPrincipal的傳回值相同。要注意的是在調用鏈中傳遞的是使用者的標識,而不是憑證(credentials),這一點非常重要,因為在調用鏈的每個節點上使用者可能使用不同的安全屬性。
Run As Identities
J2ee 1.3中提供了允許組件開發人員和部署這來指定組件以什麼身份啟動並執行方法。符合j2ee1.3規範的產品會提供將組件設定成Run As Identities方式的方法。如果Run As Identities方式被選中,在運行中被設定為Run As Identities的組件的調用者不再是調用鏈中第一個節點的調用者了,而是在部署時被指定的調用者。而調用鏈中隨後節點的調用者也變為與被設定為Run As Identities的組件的調用者相同。
圖四 使用者標識傳遞
這一部分介紹了j2ee的安全概念,意在使讀者能夠對j2ee在安全方面有一定的瞭解,後面還會有應用這些概念的具體例子。
小結
j2ee為我們提供了對於驗證和授權的安全服務,在開發基於j2ee的應用時應該儘可能的使用j2ee為我們提供的這些服務。因為只有遵循j2ee標準,才能使你的應用具有良好的移植性、擴充性和可維護性。只有在所選j2ee產品不能滿足特定的安全需求時,才應該考慮使用第三方安全產品或自己開發安全服務。
來源:http://www.ibm.com/developerworks/cn/java/l-j2eeSecurity/