基于XFire實施WS-Security
概述
Web Service是安全的嗎?鑒于安全性涉及諸多方面(例如身份驗證和授權、數據隱私和完整性等),而 SOAP 規范中根本沒有提及安全性這一事實,所以我們不難理解人們為什么認為答案是否定的。
很少有不需要某種形式的安全性保證的企業級系統。在 Web Service中,處理Web Service安全的過程比處理其他領域應用的安全問題更為復雜,因為Web Service具有分布式、無狀態的特性。
WS-Security是解決Web Service安全問題的規范,大多數商業的Java EE應用服務器都實現了WS-Security規范,Apache WSS4J是WS-Security的開源實現,WSS4J通過SOAP中WS-Security相關的信息對SOAP報文進行驗證和簽名,XFire通過WSS4J對WS-Security提供了支持。你可以從http://ws.apache.org/wss4j了解更多關于WSS4J的信息。
認識WS-Security
2002 年 4 月,IBM、Microsoft 和 VeriSign 在他們的 Web 站點上提議建立 Web Services Security (WS-Security)規范。此規范包括安全憑證、XML簽名和XML加密的安全性問題。此規范還定義了用戶名憑證和已編碼的二進制安全性憑證的格式。
2002 年 6 月,OASIS 從 IBM、Microsoft 和 Verisign 接收到了提議的WS-Security安全性規范。不久之后就在 OASIS 成立了“Web Service 安全性技術委員會”(WSS TC)。
2006年2月15日,OASIS通過了WS-Security 1.1安全規范,1.1規范突出了對安全權標支持、消息附件和權限管理的增強。1.1規范包括WS-Security核心規范及用戶名權標規范1.1、X.509權標規范1.1、Kerberos權標規范1.1、SAML權標規范1.1、權限表達(REL)權標規范1.1、帶附件的SOAP(SWA)規范1.1和模式1.1。
也許讀者會提出這樣的問題:SSL也具有完整性和機密性,為什么還需要另外一個WS-Security規范呢?之所以要制定WS-Security規范,是SSL存在以下的問題:
- 端對端的通信,脫離傳輸層就無法保證安全性;
- 消息必須全部加密/或者全部簽名,而不能針對消息的某部分,沒有考慮XML處理。
SSL對應OSI的傳輸層,前面我們提到過Web Service是和傳輸層無關的,將安全問題依附在SSL上就違反了Web Serivce與傳輸層無關的原則。而WS-Security對應于OSI的應用層,建立消息層SOAP之上。
針對不同領域的細分問題,OASIS 在WS-Security的基礎上又制定了幾十個規范,其中包括WS-SecureConversation、WS-Federation、 WS-Authorisation、WS-Policy、WS-Trust、WS-Privacy等,形成了一個龐大Web Service安全性協議家族。
圖1 WS-Security所在位置
有了WS-Security規范,用戶就擁有在Web Service應用中實施完整性、機密性和身份驗證等安全需求的規范方法。
XFire應用WS-Security的總體方案
XFire通過Apache的WSS4J對WS-Security提供支持,XFire完整發布包中包含了WSS4J的類包。我們知道XFire在發送和接收SOAP報文前擁有多個階段,每個階段都可以注冊Handler,對SOAP報文進行前置和后置處理的加工操作。XFire即通過Handler實施WSS4J,當發送SOAP報文時,通過注冊一系列OutHandler,對SOAP報文進行加密、簽名、添加用戶身份信息等后置處理操作。而在接收SOAP報文時,則通過注冊一系列的InHandler對SOAP進行解密、驗證簽名,用戶身份認證等前置操作。
圖2 XFire應用WS-Security的方案
請求和響應的SOAP在發送之前可以通過注冊的OutHanlder進行加工處理,讓SOAP轉換為WS-Security的保護格式。而服務端和客戶端的接收SOAP 報文之前,可以通過注冊的InHandler,將WS-Security格式的SOAP轉換正常的SOAP進行處理。
由于XFire在SOAP收發過程中定義了多個不同的生命階段,所以可以在發送前和接收前完成SOAP報文安全處理的工作,這些操作完全獨立于業務處理邏輯,實施WS-Security對于Web Service的業務操作是透明的。
使用WS-Security
在前面內容中,我們通過各種方式將BbtForum中的方法以BbtForumSerivice窄接口開放為Web Service服務,但個Web Service是沒有任何安全性可言的,任何拿到WSDL的人都可以輕松地構造客戶端程序訪問我們的Web Service服務。在這節里,我們將解決這個問題,對BbtForumSerivice添加不同的安全功能。
準備工作
在使用XFire的WS-Security之前,必須做一些準備性的工作:包括搭建安全環境,創建密鑰對和證書等內容。
安裝Java策略文件
策略文件被JDK使用,用以控制加密的強度和算法。確認已經安裝對應JDK 版本的Unlimited Strength Jurisdiction策略文件,這是一個無限制的安全控制文件。你可以從http://java.sun.com/j2se/1.5.0/download.jsp 或 http://java.sun.com/j2se/1.4.2/download.html頁面的底部找到下載的鏈接。否則在使用WS-Security時,可以會拋出java.security.InvalidKeyException: Illegal key size的錯誤信息。
策略文件包括local_policy.jar和US_export_policy.jar文件,將其拷貝到< JAVA_HOME >/jre/lib/security目錄下。為了方便讀者,我們在光盤resources/jce_policy-1_5_0擁有該策略文件的拷貝。
你也許會問:為何Sun不把它集成到JDK中去,而單獨“損人不利己”地弄一個鏈接出來給人下載?這是因為每個國家,尤其是美國,對涉及密碼的軟件產品控制非常嚴格,在美國國內,很多密碼算法長度都作了限制,而且某些算法在某些國家沒有申請專利,可以隨意使用,而在某些國家卻做了明確限制,不準使用,因此Sun必須按照慣例行事。
安裝SecurityProvider
WSS4J使用了BouncyCastle的SecurityProvider,所以需要事先在java.security文件中進行配置,否則運行加密模式的XFire認證時,會拋出以下的出錯信息:org.apache.ws.security.WSSecurityException: An unsupported signature or encryption algorithm was used unsupported key
在java.security文件中(位于< JAVA_HOME >/jre/lib/security目錄中)添加BouncyCastleProvider的配置:
…
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider
…
XFire發布包中包含了BouncyCastle SecurityProvider的類包,位于< XFIRE_HOME >/lib/bcprov-jdk15-133.jar下。必須將bcprov-jdk15-133.jar加入到類路徑中。你可以在http://docs.safehaus.org/display/PENROSE/Installing Security Provider中獲取更多關于安裝BouncyCastle SecurityProvider的幫助。
創建密鑰對和數字證書
簽名和加密需要使用到數字證書和密鑰對,可以使用JDK提供的KeyTool工具創建密鑰對和數字證書。我們分別為服務端和客戶端創建RSA密鑰對,并生成各自的X509數字證書(包含公鑰和數字簽名)。服務端和客戶端擁有各自的密鑰庫JKS文件,服務端的密鑰庫保存服務端的密鑰對和客戶端的數字證書,而客戶端的密鑰庫保存客戶端的密鑰對和服務端的數字證書。
下面,我們來完成創建服務端和客戶端密鑰庫的工作:
- 編寫一個用于創建RSA密鑰對和generateKeyPair.bat批處理文件:
rem @echo off
#接受參數
echo alias %1
echo keypass %2
echo keystoreName %3
echo KeyStorePass %4
echo keyName %5
①創建RSA 密鑰對
keytool -genkey -alias %1 -keypass %2 -keystore %3 -storepass %4-dname "cn=%1" -keyalg RSA
keytool -selfcert -alias %1 -keystore %3 -storepass %4 -keypass %2? ②使用私鑰進行自簽名
keytool -export -alias %1 -file %5 -keystore %3 -storepass %4? ③導出數字證書
- 編寫一個使用generateKeyPair.bat創建服務端和客戶端的密鑰庫的generateKeyStore.bat批處理文件:
①下面兩行命名分別調用generateKeyPair.bat 批處理文件為服務端和客戶端生成密鑰對
call? generateKeyPair.bat ?server serverpass serverStore.jks storepass serverKey.rsa
call? generateKeyPair.bat ?clientclientpassclientStore.jks storepass clientKey.rsa
②將服務端的數字證書導入客戶端的密鑰庫
keytool -import -alias server -file serverKey.rsa -keystore clientStore.jks -storepass storepass -noprompt
③將客戶端的數字證書導入服務端的密鑰庫
keytool -import -alias client -file clientKey.rsa -keystore serverStore.jks -storepass storepass -noprompt
運行該批處理文件后,將分別為服務端和客戶端生成一個Java密鑰庫文件,它們分別擁有一個自己的密鑰對和對方的數字證書。我們通過表1對兩者密鑰庫文件的內容進行說明:
表 1密鑰庫說明
? |
服務端Java密鑰庫 |
客戶端Java密鑰庫 |
對應密鑰庫文件 |
serverStore.jks |
clientStore.jks |
密鑰庫密碼 |
storepass |
storepass |
庫中包含的內容 |
server密鑰對、client數字證書 |
client密鑰對、server數字證書 |
密鑰對別名 |
server |
client |
密鑰對私鑰的保護密碼 |
serverpass |
clientpass |
- 將serverStore.jks和clientStore.jks拷貝到< 工程目錄 >/src/META-INF/xfire的目錄下,以便后面的實例代碼使用。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
