閱讀本文前您需要以下的知識和工具: Apache axis1.1,並且會初步使用; Tomcat 5.0.16以上, 並且會初步使用; SOAP訊息(SOAP Message)編程知識; Java安全編程基礎知識; JAX-RPC編程基礎知識; Servlet的開發經驗; Sun提供的JAX-RPC參考實現(jaxrpc-impl.jar,在J2EESDK1.4或者JWSDP1.4中可找到); 一個JSSE安全提供者(如ISNetworks); Trust Services Integration Kit,可在http://www.xmltrustcenter.org上獲得。
本文的參考資料見 參考資料。
本文的全部代碼在這裡 下載。
Web 服務安全性相關技術和開發工具
Web 服務安全性規範是一套可以協助 Web 服務開發人員保證 SOAP 訊息交換的安全的機制。WS-Security 特別描述了對現有的 SOAP 訊息傳遞的增強,從而通過對 SOAP 訊息應用訊息完整性、訊息機密性和單訊息認證提供了保護層級。這些基本機制可以通過各種方式聯合,以適應構建使用多種加密技術的多種安全性模型。
圍繞Web服務的安全,有很多相關的技術,比如WS-Security,WS-Trace等,另外,還有以下相關技術: XML Digital Signature(XML數位簽章) XML Encryption (XML加密) XKMS (XML Key Management Specification) XACML (eXtensible Access Control Markup Language) SAML (Secure Assertion Markup Language) ebXML Message Service Security Identity Management & Liberty Project
由於本文是一個執行個體性文章,故不對WS-Security做詳細的探討,你可以在develperWorks Web 服務安全專題找到許多相關資料(見參考資料)。
Trust Services Integration Kit提供了一個WS-Security實現。你可以從http://www.xmltrustcenter.org獲得相關庫檔案,分別是wssecurity.jar和tsik.jar。wssecurity.jar中包含一個WSSecurity類,可以使用它來對XML進行數位簽章和驗證,加密與解密。
下面我們使用WS-Security來對SOAP訊息進行數位簽章,然後再進行驗證。
SOAP訊息的簽名和驗證
使用WSSecurity對SOAP訊息數位簽章
在對SOAP訊息進行簽名前,首先產生一個keystore。keystore包含了進行數位簽章所需要的身份資訊。通過以下批處理指令碼來建立keystore:
常式1 建立keystore(server.keystore)
SignAndVerifySoap類中包含了一個對XML進行簽名的方法,它就是sign(),這個方法將對SOAP訊息進行簽名,然後輸出和WS-Security相容的SOAP訊息。下面我們看具體代碼。
常式2 對SOAP訊息簽名
在執行此程式前,請把wssecurity.jar、source.xml和tsik.jar設定到類路徑環境變數中。簽名前的SOAP為:
常式3 簽名前的SOAP訊息(source.xml)
簽名後的SOAP訊息如常式4所示。
常式4 簽名後的SOAP訊息(signed.xml)
簽名後的SOAP訊息中,頭部包含了簽名資訊以及驗證SOAP訊息所需要的key。<SignedInfo> </SignedInfo> 描述了已簽署的訊息內容。<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> 指出了簽名演算法(Signature Method Algorithm)。這個演算法被用來將規範演算法的輸出轉換成簽名值(Signature Value)。Key Info 元素包含的部分就是數位憑證本身。
對簽名的SOAP訊息進行驗證
對SOAP訊息進行驗證就是使用keystore的資訊產生TrustVerifier對象,然後調用WSSecurity的verify方法進行驗證。
常式5 驗證簽名後的SOAP訊息
執行SignAndVerifySoap的verify方法,可以看到類似以下的結果。
圖1 對SOAP訊息進行驗證
在AXIS下實現WS-Security的應用程式框架
待開發的應用開發架構基於Handler實現,將達到以下目標:此架構基於JAX-RPC環境下實現WS-Security應用,它可以部署到任何需要實現WS-Security的axis環境下的Web服務應用中,同時具體的應用程式不做任何編碼修改。
由於此基於Handler實現,我們有必要回顧一下Handler的一些基礎知識。
SOAP訊息Handler能夠訪問代表RPC請求或者響應的SOAP訊息。在JAX-RPC技術中,SOAP訊息Handler可以部署在服務端,也可以在用戶端使用。
SOAP訊息Handler非常像Servlet技術中的Filter,它們共同的特點是請求發送到目標前,Handler/Filter可以截取這些請求,並對請求做一些處理,從而達到一些輔助的功能。多個Handler可以組成一個Handler鏈,鏈上的每個Handler都完成某個特定的任務。比如有的Handler進行許可權驗證,有的Handler進行Tlog等。關於Handler更詳細的介紹,請參考本系列文章《 J2EE Web服務開發系列之六: 使用Handler來增強Web服務的功能》。
實現原理
圖2是此例子具體實現原理圖。
圖2 Handler結合WSSecurity實現Web服務安全的工作原理
處理流程如下:
1、 用戶端(WSSClient)發出調用Web服務要求;
2、 用戶端Handler(WSSecurityClientHandler)截獲請求的SOAP訊息;
3、 用戶端Handler對截獲的SOAP訊息進行數位簽章(使用client.keystore作為簽名依據);
4、 用戶端Handler對簽名後的SOAP訊息進行加密(使用RSA演算法加密);
5、 被加密的SOAP訊息通過互連網傳送到目標Web服務連接埠;
6、 伺服器端Handler(WSSecurityServerHandler)截獲加密的SOAP訊息;
7、 伺服器端Handler對加密的SOAP訊息進行解密;
8、 伺服器端Handler對SOAP訊息進行身分識別驗證(server.truststore包含了所信任的身份資訊),如果驗證不通過,將拋出異常;
9、 伺服器端Handler刪除被解密後的SOAP訊息中與WS-Security相關的元素;
10、 解密後的原始SOAP訊息被發送到目標Web服務連接埠(如TaxService); 11、 目標Web服務對Web服務要求進行處理,然後返迴響應的SOAP訊息;
12、 伺服器端Handler截獲響應的SOAP訊息;
13、 伺服器端Handler對截獲的SOAP訊息進行數位簽章(使用server.keystore作為簽名依據);
14、 伺服器端Handler對簽名後的SOAP訊息進行加密(使用RSA演算法加密);
15、 被加密的SOAP訊息通過互連網傳送到目用戶端;
16、 用戶端Handler截獲加密的SOAP訊息;
17、 用戶端Handler對加密的SOAP訊息進行解密;
18、 用戶端Handler對SOAP訊息進行身分識別驗證(client.truststore包含了所信任的身份資訊),如果驗證不通過,將拋出異常;
19、 用戶端Handler刪除被解密後的SOAP訊息中與WS-Security相關的元素;
20、 被解密後的SOAP訊息發送到勘探端,用戶端輸出調用結果。
從上面可以看出,在一個SOAP調用回合中,要對SOAP訊息進行四次處理。基本上都是"簽名'加密'解密'驗證"的過程。
建立相關密匙庫
用戶端和服務端都有相關的密匙庫,其中: client.keystore:用戶端自身的身份資訊; client.truststore:用戶端所信任的身份資訊,在此例中也就是包含了伺服器的身份資訊; server.keystore:伺服器自身的身份資訊; server.truststore:伺服器所信任的身份資訊(即用戶端身份資訊)。
你可以使用以下的批處理指令碼建立上面四個密匙庫。
常式6 建立相關密匙庫(gen-cer-store.bat)
簽名、加密、解密、身分識別驗證的實現
對SOAP訊息的簽名、加密、解密、身分識別驗證都放在一個名為WSSHelper的類中進行。
常式7 簽名、加密、解密、身分識別驗證功能的實現――WSSHelper.java
WSSHelper類中使用了ISNetworks安全提供者,ISNetworks實現了RSA加密、解密演算法。當然,你也可以使用其它的安全提供者,並且可以使用不同的密碼編譯演算法。可以從網路上下載ISNetworks相關包。
WSSHelper中包含了一個WsUtils類,它的功能就是從加密後的SOAP訊息中刪除一些WS-Security元素,刪除這些元素後的SOAP訊息才能被最終的用戶端或者Web服務端處理。
伺服器端Handler開發
當請求到達後,服務端Handler調用handleRequest方法,執行如下過程:對請求SOAP訊息解密'身分識別驗證'刪除WSS元素'把Document轉換成SOAP訊息。 Web服務端點對請求做出響應後,將調用handleResponse方法,執行如下過程:對響應的SOAP訊息進行數位簽章'加密'把Document轉換成SOAP訊息。
常式8 伺服器端Handler(WSSecurityServerHandler.java)
用戶端Handler開發
用戶端Handler可以是任何JAX-RPC相容的Handler處理器。比如AXIS Handler實現或者SUN 提供的JAX-RPC Handler參考實現。這裡使用後者來作為用戶端Handler處理器。
用戶端Handler和伺服器端Handler原理一樣,但處理過程完全相反。
常式9 用戶端Handler(WSSecurityClientHandler.java)
部署伺服器端Handler
為了使用Handler,需要在Web服務部署描述符中指定使用此Handler。Handler包含的初始化參數也在此描述,如常式10所示。
常式10 伺服器端Handler部署代碼
requestFlow表示Web服務PersonalTaxServicePort的請求處理Handler鏈。這裡只有一個Handler,就是WSSecurityServerHandler。當Web服務要求到達PersonalTaxServicePort時,WSSecurityServerHandler的handleRequest方法將被自動調用。
注意:部署時,請改變Handler相關參數以和目標的Web服務一致,比如trustStoreFile的路徑等。
調用測試
這裡採用代理的方式來調用Web服務,先編寫一個Web服務介面。
常式11 TaxServiceInterface
WSSClient用戶端程式是通過代理的方式來訪問Web服務的。由於要使用Handler,所以在訪問前通過registerHandlers()方法註冊了WSSecurityClientHandler,並且初始化了WSSecurityClientHandler的相關參數。當然,JAX-RPC"參考實現"還支援在Web服務用戶端設定檔中描述Handler資訊,這樣就不需要在用戶端代碼中對Handler進行註冊了,你可以參考相關文檔。
常式12 測試用戶端程式(WSSClient)
注意:由於用戶端使用了SUN公司提供的"JAX-RPC參考實現",所以必須把jaxrpc-impl.jar包設定在CLASSPATH環境變數中,並且不要把axis.jar設定在用戶端CLASSPATH環境變數,否則會出現ClassCastException異常。這是因為axis也是JAX-RPC的實現,如果它在CLASSPATH環境變數中,當調用:
ServiceFactory svcFactory = ServiceFactory.newInstance()方法時,就可能初始化一個axis的ServiceFactory 實現。
本文原始碼中client目錄下wss-client.bat檔案包含了執行WSSClient指令碼,修改了部分環境變數參數後,才能執行。
總結
本文和上一篇文章介紹了幾種不同實現Web服務安全的方法,你可以根據具體應用對安全的要求層級採用不同的方式。對於安全層級要求不高的應用,可以採用在Web伺服器上使用基本認證、使用Axis的Handler或者使用Servlet過濾器來實現存取控制;對於安全要求高的應用,可以採用本篇介紹開發的"axis下實現WS-Security的跨平台 app架構"來實現安全性。
參考資料 Java安全編程
VeriSign Trust Services Integration Kit
配置Tomcat 4使用SSL
Sun jwsdp-1_1-tutorial
SOAP 安全性擴充:數位簽章
SOAP-DSIG 定義了一種向 SOAP 訊息中附加XML 簽名的資料格式
XML 加密工作群組
SOAP Header擴充:WS-Security和WS-License
SOAP訊息的數位簽章教程
Web 服務安全專題
J2EE Web服務開發系列之六: 使用Handler來增強Web服務的功能
關於作者
|
|
|
陳亞強:北京華園天一科技有限公司進階軟體工程師,擅長J2EE技術,曾參與多個J2EE項目的設計和開發,對Web服務有很大的興趣並且有一定的項目經驗。熱愛學習,喜歡新技術,曾參與多本圖書的寫作。好交朋友,您可以通過 cyqcims@mail.tsinghua.edu.cn和他聯絡。 |