Web Service 、WS-Security、Java和.net的互通

和第三部分同樣,這部分內容其實應該在後面纔對,不過當前工作既然做了,也需要寫下來分享,那麼就提前插隊到成長記錄當中吧。看了這篇文章以後,可能給人的感覺是有點偏離服務框架的內容。的卻,如果純粹從技術方面來說,這部分應該不屬於服務框架範疇。拿杭州作個例子,杭州是全國唯一一個景點不但漲價,反而免門票的地方,原因何在,無非是管理者看得遠,景點的門票收益看得到,但是小頭,免去門票帶來的商機那纔是金礦。框架其實也是這樣,如果客戶用起來不方便,甚至都不能用,那麼框架再好,也會有人笑話你是個高高在上的理論主意者,這種框架適合於教學,而非實用。現在也是在邁出平臺服務框架兼容性的第一步,那天和同事們開玩笑說,以前聯通移動的wap業務,好在大家的開發語言都相似,isp只需要兼容各種手機客戶端,我們現在要做的就是兼容各種不同開發語言,平臺,以後甚至瀏覽器,我們這種全部都搞通的人出去,那就真的是搶手貨了。

週一測試部ISV support小組的日報反映,.net的客戶端對於複雜對象數組返回有問題,緊接着就是.net客戶端對於web servicewsse無法調試通過。我以前沒有接觸過.net,沒辦法,硬着個頭皮裝了個vs2005WSE 3。前面一個問題就是我前面半周間斷性的解決的問題,在第三篇記錄中也寫了。後面的問題比較緊急,也比較嚴重,因爲如果wsse不能順利調試通過,那麼將會直接影響我們後續將wsse全面部署的計劃,同時ISV已經跟在後面作測試了。看了看時間進度表,下週要進入平臺搜索引擎增強的開發和WSSE性能優化(WSSE對於CPU的消耗真是厲害),因此也就只有兩天,週四和週五。昨天晚上調試到了很晚(我說的很晚可能有些朋友覺得很早,不過對於我這種早睡早起的人來說,真的算晚了),雖然盡力了,但是還是卡在了最後的部分(服務端返回內容的驗證解析),週五一大早到公司就開始繼續調試,一直到了下午5點鐘,我的神哪,讓我看到那個斷點不再跳出一個令我已經看到都反胃的出錯提示框(順便說一下,微軟的vs出錯提示框作的蠻精緻,不過再好看都是出錯,2天內看到了不下數百次,再好看也讓人反胃了),最後在羣裏面大大的發泄了一把,公司一堆人覺得莫名其妙,不知道我受了什麼打擊,就搞通一個東西能夠壓抑成這樣,其實這其中的苦也就自己知道,還是那句話:“在沒有調試過.net的程序以前不知道開源的好啊,能看到源碼是多麼開心的一件事情啊,整一在替微軟作白盒測試,連google都被我翻爛了,也就只看到幾個老外在Q,而沒有人在那兒A”。廢話說了那麼多,言歸正傳,實踐是建立在理論基礎上的,那麼先系統性的來介紹一下關於WSSE的內容(如果概念已經十分熟悉了,跳過即可),以及如何解決.net客戶端無法調試Java發佈的web service的問題。

 

在互連網應用中Web Service已經得到了廣泛的認同,同時也是因爲這種廣泛的應用,使得Web Service在規範化方面越來越成熟。企業和企業之間的信息交互,很重要一點就是信息的安全性,電子商務等互連網應用這方面的需求更爲突出,如果沒有安全的保證,沒有客戶或者企業願意將信息在網上交互,同時也不會信任任何接受到的信息。然而,作爲SOA的有效技術手段,Web Service的動態性很強,服務的開發者無法預料到服務將在什麼環境下被使用,因此服務的安全性變得更加複雜。

在考慮安全性方面主要有三個關鍵性的概念:

機密性(Confidentiality),完整性(Integrity,身份鑑別(Authentication)。

機密性:除了指定的接受者,其他人無法查看消息的內容。通常會使用密鑰(對稱或非對稱)對消息加密,從而保證消息的機密性。     完整性:確保消息在傳輸的過程中沒有被修改。即保證消息的接收者接收到的消息與消息發送者最初發送的消息完全一致。通常會對消息做摘要(Digest),再使用密鑰(對稱,非對稱)加密摘要,從而保證消息的完整性。   

身份鑑別:確保消息發送者的身份與消息中所聲稱的用戶身份一致。最簡單的做法就是讓用戶同時發送用戶名和密碼,服務方確認密碼的有效性從而判斷該用戶身份是否與用戶名所代表的一致。然而在實際的應用中的做法通常不會如此簡單,此時往往會使用密鑰對一段信息加密,服務方通過解密此信息確認用戶的身份。

那麼如何選擇使用對稱密鑰還是非對稱密鑰?什麼時候使用公,什麼時候使用私?首先由於對稱密鑰的加密解密速度比非對稱的密鑰快很多(大約1000倍),所以在加密消息的時候一般都使用對稱密鑰。但是有一個問題就是對稱密鑰又如何發佈呢?網絡上兩個沒有聯繫的用戶如何建立起一個共享的密鑰?這時就需要PKI來幫助我們將這個共享的密鑰建立起來,即利用非對稱密鑰中的公來加密那個共享密鑰,傳遞到私的擁有方。由此可以知道:對稱密鑰加密普通信息,非對稱密鑰加密對稱密鑰。

Integrity,使用非對稱密鑰的私加密摘要,得到的東西是一個廣爲人知的東西Digital Signature(數字簽名). 而使用對稱密鑰加密摘要得到的是HMAC(Hash message authentication codes)。他們在保證消息完整性的同時,都具有身份鑑別的功能,不過前者還有一個功能---抗否認性。值得注意的是在Confidentiality中,使用非對稱密鑰方法是用公加密,私解密,而在Integrity中使用非對稱密鑰的方法恰恰相反。

在當前的安全策略上很多時候會使用到SSLVPN,他們的好處和缺點網上都有評論,但作爲和傳輸層無關的安全策略,WS-Security規範無疑是最具廣泛的應用。IBMBEA,Microsoft共同制定了WS-Security規範,解決了安全的三個基本問題:機密性、完整性、身份鑑別,在Web Services使用SOAPXML 格式)作爲消息封裝協議的背景下,標準化組織分別制定了XML EncryptionXML Digital Signature、與SAML(XML格式的Security Token)三套規範,WS-Security則是規定了如何將以上規範組合起來以滿足Web Services安全需求的一套規範。

XML Signature規範是將數字簽名和XML組合而成的產物,不要以爲XML Signature僅僅是將數字簽名技術應用於XML文件。

XML Signature包括以下的功能:

    1XML Signature可以對任何能夠以URI形式(uniform resource identifier)定位的資源做簽名。既包括與簽名同在一個XML文件中的元素,也包括其他XML文件中的元素,甚至可以是非XML形式的資源(比如一個圖形文件),只要能被URI定位到的資源都可以應用XML Signature. 這也代表了XML簽名的對象可以是動態的變化。

    2XML Signature可以對XML文件中的任一元素做簽名,也可以對整個文件做簽名。

    3XML Signature 既可以用非對稱密鑰做簽名(Digital Signature),也可以用對稱密鑰做簽名(HMAC)

具體的標籤以及含義就不做解釋了,不過如果要做簽名策略配置,需要熟悉這些標籤,這也會影響到後續開發中遇到的各種問題。另外兩個規範這邊就不做說明了,因爲現在服務框架暫時只是提供了Signature的要求,如果內容需要加密,那麼對於應用來說性能可能是不可接受的,因此需要的是利用SSL和簽名結合的策略來實現完整的安全機制。

 

對於WSSE的支持

       ASF這部分是改造了TusncayWeb Service子項目,Tuscany子項目內部集成的web service的開源框架是axis2,雖然很多朋友評價xfire好於axis2,不過個人在使用過程中感覺其實兩者各有所長,只是說如何在適當的場合使用,如果需要和Spring很好的集成,那麼xfire當然是最好的選擇,如果需要能夠有很好的wsse以及其他開源支持,那麼axis2應該是個很不錯的選擇,畢竟apache組織下的開源項目衆多,自家人集成起來更是得心應手,特別是wss4jaxis2的集成,axis2addressrampart兩個子插件模塊使用起來十分方便,同時在框架的可插入性和模塊化上,覺得axis2要好過xfire。不過axis2的客戶端比xfire要麻煩得多,xfire封裝的好多了,這也是很多人喜歡xfire的緣故了(不過再傻瓜也抵不過.net客戶端的傻瓜,不過這個傻瓜模式無法讓人測試,那麼就真的被當成傻瓜了),畢竟易用性往往是吸引到第一批客戶的重要特質,這也是後續做ASF所需要考慮的問題。

       使用Axis2的框架結合Jetty這個輕量級內嵌容器作爲Web Service發佈框架(不得不提的是,在作web service的性能測試的過程中,公司的測試資深人員對於ASFweb service性能作了肯定,其實這和使用Jetty也有一定的關係,現在越來越多的開源框架都使用了Jetty作爲內置web輕量級容器,很靈活,同時也可以達到很好的性能要求,在後面工作中對於hessian集成到服務框架中來,也是採用了Hessian+Jetty),並且通過Axis2rampart集成了wss4j,提供了WSSE的增強功能。

 

對於認證模式場景需求問題的解決

       ASF對於Web Service Security這部分只是要求了Signature,而對於Signature需要提供兩種方式,UserNameTokenX.509證書。前者提供給內部的一些應用使用,後者提供給外部ISV使用,兩者主要差別也就是在性能上,後者經過測試,在CPU的使用上,是6-8倍於不帶SignatureWeb Service

       UserNameToken這種模式很簡單,就很類似於我們平常的用戶認證,用戶名和密碼作爲明文或者加密,嵌入在Soap Header中即可,客戶端根據本地保存的受信用戶記錄來交驗是否是合法用戶。

       X.509就比較特殊一些,所謂的證書,其中包括了公對(作爲簽名和認證使用),證書頒發者的信息(可能是一些CA機構或者是用本地的證書生成工具自己生成),證書擁有者的身份信息,以及一些導入的受信第三方的公證書。當前的證書方式的簽名認證主要有兩種模式,一種是雙方證書都是由第三方CA認證,同時雙方都將對方的CA作爲可信的CA,那麼請求發起方將會把自己的證書放入到Soap Header中,接受方接受到請求以後,獲取證書,發現是受信的CA,那麼就認爲請求發起方身份可信,同時在作完整性摘要校對。另一種模式就是雙方的證書可以沒有任何權威的CA作保證,但是雙方首先就需要將附帶自己公的證書發送給對方,對方將這附帶有公的證書分別導入到證書管理庫中(java是某個JKS.netwindows的當前用戶或者本機的證書管理文件)。雙方交互的時候不需要將證書置入Soap Header中,但是需要將證書的引用標示(序列號或者是X.509 SubjectKeyIdentifier)傳遞給服務端,服務端根據標示在本地的證書庫中查找並且校驗,這種模式的好處就是不需要CA的認證(省錢)同時傳遞的時候不需要將證書帶入到Header中,節省了傳遞報文的大小,缺點就是雙方需要互相保存對方的公證書到本地的證書庫中,同時這種模式也爲跨平臺帶來了很多問題,後續的互通中就會提到。

       ASF的證書認證模式中採用了後者,因爲要求每個ISV去有一個第三方CA作爲授權不是很可行,但是問題就是如果ISV需要導入我們的公證書比較方便,但是我們需要管理那麼多ISV的證書,同時又需要動態上傳修改保存證書那麼就不能用原有的手動導入的模式,同時由於到時候部署的服務器集羣不可能都維護一份本地的證書庫,因此需要用數據庫手段來維護,但是在應用啓動以後再要新增或者修改證書,將會比較麻煩,因此採取了擴展wss4j的策略讀取方式來適應新的應用場景。

      

擴展的CrytoProvider類圖

擴展後的keystore 初始化以及signature部分流程圖

         這部分設計主要是擴展了WSS4JCrytoProvider,擴展後的CrytoProvider重載了獲取X509證書的幾個方法,這裏類似於AOP,通過提供ICertsLoaderHandler接口來回調獲取其它存儲內的certs 構建 visual keystore,同時在作signature的時候,如果發現ISVcert不存在於當前的visual keystore 中根據CrytoProvider的接口實現,來決定是全部刷新還是部分獲取刷新當前的visual keystore中的certs。這樣就可以達到了動態裝載和刷新certs的要求,同時根據性能要求選擇配置和實現不同的CrytoProvider

 

.NetJava的互通

       Java 的客戶端和服務端Security互通很快就搞定了,只是對於一些應用場景做證書管理的擴展。然而,在經歷了.net客戶端調用Java發佈的ws返回數組對象類型的問題以後,又一個大難題擺在了我的面前,ISV support小組和測試部的日報上把.net客戶端無法在wsse的模式下調用Java 發佈的 Web Service作爲了重點問題,需要我支持,那麼當然當仁不讓的接下來儘快搞定了,雖然對.net來說,我算是新手中的新手,不過經過兩天的測試,讓我總結出了.net調試的技巧,那就是截包分析(感覺又回到我前幾年在通信行業幹活時的狀況,對於對方協議不瞭解,又沒有源碼可看,那麼就截報文來分析麼)。開始挺樂觀的,想着WS-Security微軟也是參與者麼,應該會嚴格遵守的,估計一天搞定,結果活活的折騰了兩天,下面所描述的如何互通可能總的看起來應該不是很複雜,不過摸索的過程可真是很費事,google的每一條老外的信息都被我看過了,但是QuestionAnswer少。廢話不多說,進入正題。

       首先不管是什麼客戶端調用什麼服務端,都需要先做一件事情,準備key pairs。在Java中證書管理庫可以通過Jdk提供的key tools這個工具生成jks格式的Java Key Store,可以將公導出,或者將公導入,同時可以生成祕對保存在證書中。在.net中可以通過makecert的工具來生成符合Public Key Cryptography Standards #12PKCS#12標準定義,包含了公私鑰的二進制格式的證書形式,以pfx作爲證書文件後綴,同時可以通過mmcwindows的證書存儲區進行管理,導入或者導出證書。其實.netjava的互通關鍵問題就是出在證書格式不同以及獲取證書的算法上。下面就具體的描述一下如何從Java的開發者來做好Java WebService.net互通的工作。

 

一.準備雙方的證書和公

首先通過Javakeytools 生成了兩個jks,一個叫做alisoft.jks,另一個叫做myisvdemo.jks,這裏需要注意,在使用keytools生成證書的時候會提示需要輸入兩個密碼,一個是keystore的密碼(每次對keystore作操作的時候都需要輸入密碼來驗證),另一個是私保護密碼(使用私作簽名或者加密的時候需要輸入),這兩個密碼可以設置爲不同的值,不過爲了後面轉換爲.netpfx格式的證書需要,兩者需要設置爲相同,同時在早期的tomcat中使用證書也有這種限制。然後將兩個證書都自簽名並將公導出,分別叫做alisoft.rsamyisvdemo.rsa(因爲我這裏用的是rsa算法,所以用了這個後綴,其實可以直接命名爲.cer後綴,因爲它們的類型其實就是base64編碼後的沒有私的證書,可以直接導入到windows中)。

準備好了這四份文件以後,將myisvdemo.rsa導入到alisoft.jks中(由於測試不採用上面提到的數據庫存儲的方式,因此直接導入作測試)。然後,通過一個叫做jks2pfx的工具包,將myisvdemo.jks轉成爲myisvdemo.pfx文件,通過mmc導入到本地計算機的證書管理中。

這時候,雙擊這兩個證書都會顯示當前的Ca根證書不受信任,可以直接拖動複製增加到受信任的根證書頒發機構的證書中,就不會再顯示這樣的提示了。最後分別將這兩個證書在複製到受信任人的證書中。至此,客戶端和服務端的證書都已經準備好了,接下去就是如何配置使用.net的客戶端來調用已經發布成爲帶有WSSEJava Web Service了。

 

二.配置.net的客戶端

首先,作爲測試就建立了一個C#Windows Application,然後在默認的form上面加了一個button作爲激發調用服務端的事件控制載體。用.net來調用web service通常情況使用增加一個web reference來注入這個遠程服務,不過這邊要特別特別強調,如果你要使用WSSE的話,不要急於先建立一個Web Reference,首先要將你的安全策略配置好,然後再建立web reference,不然自己手動的要去修改後臺客戶端代碼。那麼接着來說.netWSE

.net提供的WSEWeb Services Enhancements)是用來增強對於Web Service的支持配置(包括了WS-Security等規範)。當前.netWSE最新版本是3.0的,可以很方便的集成到VS2005中,而它的2.0版本主要是針對過去的VS2003版本,不過兩者都是可以用的,但是在配置上面有一些差異,同時使用的方便程度也有些差距,2.0使用起來相對3要複雜一些。不過我們這裏介紹的都是通過設置WS-Policy來應用WS-Security,這樣比較方便,同時代碼簡潔,業務邏輯和具體的WS配置分開,是一種較好的使用模式,.net也支持代碼內嵌WS-Security邏輯來實現WS-Security的使用。

       先來說一下3如何使用。安裝好3以後,可以在我們的項目右鍵菜單中最下面看到WSE 3.0 setting,直接選擇這項,彈出類似的設置頁,第一頁最頂上的一項選中。

       然後選擇Policy Tab頁面設置,首先選中Enable Policy,然後選擇Add,輸入一個Policy的名稱,後面就是一個嚮導配置頁面,第一頁的選擇如下圖

       後面第一個要選擇的x.509證書是本地的密碼對存在的證書,也就是用來簽名並向服務端發起請求的證書所在位置,選擇了LocalMachine,然後再選擇證書,也就是上面我導入到系統中的myisvdemo證書。然後出現如下圖

       將配置修改成圖中所示,首先不要選擇支持1.1擴展,因爲.netjava1.1擴展的支持實現有所差異,特別是簽名回執上,連域名都不一致,所以使用起來有問題。然後我們現在只是要用sign-only的功能,因此就選擇這項。

       下一頁是選擇服務端響應時使用什麼證書作爲解析的證書,這裏就選擇local Machinealisoft證書。至此Policy全部配置完成,關閉配置文件。在我們的工程裏面會新增加一些文件,如下圖所示:

       其中在references中的是引入的第三方包,主要是爲了將普通的web Service的代理類轉變成爲支持WSSE的代理類(這也是爲什麼我說不要先急着建立web reference的緣故,如果先建立web reference的話),打開Reference.map中的reference.cs文件,可以看到服務代理類是繼承System.Web.Services.Protocols.SoapHttpClientProtocol,而如果在配置好策略以後服務代理類就會自動繼承 Microsoft.Web.Services3.WebServicesClientProtocol,此時的服務代理類纔可以支持WSSE的功能,因此如果先建立reference就要手動的去修改這些客戶端文件。

    然後打開wse3policyCache.config文件,這個文件就是剛纔配置的Policy文件,修改establishSecurityContext="false",這個參數如果爲true的話,會連續兩次發送請求,後一次的請求內將不帶有Policy中配置的信息(這個具體的我還不是很清楚,只是看到一個國外的人詢問微軟工程師的時候,認爲這個是個缺陷,但是微軟工程師則認爲這是一個讓用戶集成自己配置的擴展點,不過個人認爲,所謂擴展點應該是在默認沒有擴展的時候不影響原有的配置)。第二需要在我們的axis2中除了配置signature還需要配置timestamp,默認每一次請求.net都會自動將timestamp作爲action執行。

    打開app.config文件,這裏面指定了web servicepolicy配置文件,這裏沒有什麼需要修改的,只需要按照他生成的內容即可。然後建立好web Reference,這個十分簡單,就是輸入wsdlURI,然後填入服務的名稱即可。最後一部就是寫測試代碼,重新打開Form1.cs,在buttononclick事件中寫入下面的測試代碼:

private void button1_Click(object sender, EventArgs e)

        {

// AccountServiceWse是你的客戶段代理類,有WSSE的增強功能,參看reference.cs文件

            AccountServiceWse service = new AccountServiceWse();

 

            //這個客戶端代理類需要指定剛纔配置的策略名稱  

            service.SetPolicy("clientPolicy");

    

            //簡單的測試代碼

            accountService.ArrayOfAccountBean result = service.getUserAccountArr("test");

        }

噩夢開始了,到此爲止,.netweb Service開發者帶來的便利真的是無話可說,絕對的傻瓜級,但是就是這短短的幾段代碼,最後一句話執行的時候總是出現錯誤,那個黃色的小框讓我看得快崩潰了。

       根據上圖的提示,錯誤應該在客戶端這邊,Java服務端也看過,已經接收到請求並且認證簽名通過,並且反簽發送回客戶端,同時從ResponseInnerXml中拷貝出來可以看到返回的結果Soap包都是正確的,客戶端的錯誤就是Referenced security token could not be retrieved,這個就表明了客戶端的alisoft的公鑰沒有找到,導致檢查返回結果的時候出現了問題,那麼就去找是否是因爲格式不同導致公鑰沒有導入或者導入錯誤(錯誤的查錯方向)。

       最後發現原因出在了獲取key的標示上,前面說到如果不是第三方權威的CA認證模式下,需要雙方互相導入對方的公鑰到本地的證書管理庫中,我們是將Jks中的公鑰導出,然後導入到了本機的證書管理模塊中。公鑰證書的引用在WS-Security中分成兩種:SKIKeyIdentifier IssuerSerial,由於我們前面提到的擴展ISV證書動態載入的需要,我們一直使用的是IssuerSerical。但是微軟的工具生成的是x.509v3版本,而java keytools生成的是x.509v1版本,如果使用IssuerSerical會有問題。那麼只能使用SKIKeyIdentifier,但是使用SKIKeyIdentifier.net默認使用的是自身的window的序列化方式,不過可以設置其爲javaRFC3280協議方式,但是.net wse 2wse 3RFC3280方式都不一樣,wse 2的可以和java互通,wse 3就不可以,也就是說23本身在RFC3280的序列化方式上都有差別,自己也不能互通,因此沒有辦法,只能夠安裝2版本,重新來生成。下面將描述一下如何用wse 2來訂製web service WSSE客戶端。

 

WSE2客戶端的操作流程(使用的是WSE 2 sp3):

首先還是要設置WSEPolicy到新建項目中去,不過這而WSE 2沒有像WSE3那麼好的集成到VS2005中,新建好工程以後,建立Web Reference(這和WSE3不太一樣,這裏先建Web Reference,然後手動的去設置)。同樣去選擇project菜單的show all files。這時候通過外部打開WSE 2的配置工具,配置工具選擇打開新建的這個項目的app.config文件,然後開始配置策略。配置如下列圖:

       紅色部分很重要,需要選擇這種協議來序列化獲得key reference

       這裏配置策略文件有所不同,這裏首先會讓你輸入這個Policy所屬的URI,和3不同,3中是在代碼中配置進去的,在配置中只是申明,而沒有對應配置到具體的哪一個請求,這邊可以填入某一個URI,那麼你對那個URIWebService做任何請求的時候都會採取該策略,同時如果你就不填任何內容,直接用他默認的<DefaultEndpoint>,那麼所有不在指定URI對應策略中出現的URI請求和響應,都將採取這種策略,我就默認採用這種模式,因爲如果不採用這種模式,相應回來的請求就找不到可以使用的策略了(這個出錯信息也困擾我不少時間)。繼續配置下面的內容:

      

這裏我們只需要做signature,所以只配置了簽名。

這裏選擇證書根據前面頁面中配置的存儲位置相關,第一個證書是用來簽名的帶有私鑰的證書。第二個是受信的返回的簽名交驗證書。

配置完成,並保存。接下去就是要做一些wse3自動作的事情,而在wse2中需要手動修改的內容。首先把project菜單的show all files去掉,然後再選上,就會發現項目中多了一個文件:policyCache.config,選中這個文件然後右鍵選擇Include in project,不然的話每次調試都不會被拷貝到項目執行目錄下面(類似於eclipsesrc目錄中文件在調試中會被拷貝到bin目錄下),然後將這個文件的屬性Copy to Output Directory設置爲Copy always,這樣每次修改以後都會被同步過去。然後選擇項目右擊add reference,加入Microsoft.Web.Services2這個類庫,修改Web References下定義的服務的Reference.cs,將服務繼承類修改一下,例如我的項目中的服務自動生成以後這麼繼承:

AccountService : System.Web.Services.Protocols.SoapHttpClientProtocol

修改成爲:

    AccountService : Microsoft.Web.Services2.WebServicesClientProtocol

這樣定義的代理類就可以有WSSE服務增強功能了,不過注意的是如果UpdateWeb Reference的話,自動會從新生成新的客戶端代理,那麼又要手動去修改了。(發現如果再次通過wse 2 的配置工具打開app.config文件,選中General下面的框就可以類似於3自動生成了)

    然後雙擊打開policyCache.config文件,做部分的修改:

首先在文件頭部有這麼一段描述:

      <defaultEndpoint>

      <defaultOperation>

        <request policy="#Sign-X.509" />

        <response policy="#Sign-X.509-1" />

        <fault policy="" />

      </defaultOperation>

</defaultEndpoint>

這就是剛纔配置中提到的默認沒有配置固定策略的URI請求採用的策略。去查找文件中response對應的策略配置,修改其中的內容,這兒就是修改Sign-x.509-1的配置。

將:

<wsp:MessagePredicate wsp:Usage="wsp:Required" Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body() wsp:Header(wsa:To) wsp:Header(wsa:Action) wsp:Header(wsa:MessageID) wse:Timestamp()</wsp:MessagePredicate>

修改成爲:

<wsp:MessagePredicate wsp:Usage="wsp:Required" Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wsp:MessagePredicate>

因爲我們回籤的時候並沒有設置address部分,也沒有timestamp的簽名,因此都需要去掉,不然就會出錯。

再將<wssp:Integrity wsp:Usage="wsp:Required">中的:

<wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body() wsp:Header(wsa:Action) wsp:Header(wsa:FaultTo) wsp:Header(wsa:From) wsp:Header(wsa:MessageID) wsp:Header(wsa:RelatesTo) wsp:Header(wsa:ReplyTo) wsp:Header(wsa:To) wse:Timestamp()</wssp:MessageParts>

修改成爲:

<wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wssp:MessageParts>

打開app.config文件,增加如下一句(據說會有缺陷,關於超時判斷的bug,因此還是加上爲好):

<security>

      <x509 storeLocation="CurrentUser" allowUrlRetrieval="true" useRFC3280="true" />

      <timeToleranceInSeconds>86400</timeToleranceInSeconds>

    </security>

 

 

    最後在Form1.cs添加測試代碼運行測試看看,不過這裏的代碼如下:

        private void button1_Click(object sender, EventArgs e)

        {

            AccountService service = new AccountService();

 

            accountService.ArrayOfAccountBean result = service.getUserAccountArr("test");

 

        }

不在類似於WSE 3需要配置對應的策略,因爲在配置文件中已經包含了配置策略的信息。

    運行通過,艱難的歷程告一段落,一句話,平臺跨得不容易啊。

 

結束語:

    這次的WSSE跨平臺問題的查找真的花費了很多精力,也證明了我早先所擔心的,那就是對於跨平臺客戶端的兼容性測試可能問題會很多,現在纔是開始,當ISV上線調試以後,可能問題會暴露的更多,其實SAAS模式幾大技術問題中,有一項就是如何讓SOAISV和平臺之間以及ISV之間搭起橋樑,這個問題不僅框架結構上需要設計好,同時細節上也有多需要去實踐的,細節決定成敗啊,記得我在上次CSDN的採訪中談了自己對於SCA的瞭解,有一位朋友給我留了言,說還是要一些實際的開發者來說這些爲好,架構師之類的人只會玩虛的,我想我記錄着一路的歷程也就是讓大家知道,其實走好每一小步,才能夠讓系統性的架構發揮其更大的作用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章