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

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