WCF 自訂使用者帳號/密碼篇(一):Web服務(ASMX Web Service)與WCF服務(Windows Communication Foundation Service)

  • 13565
  • 0
  • WCF
  • 2022-09-18

Web服務(ASMX Web Service)與WCF服務(Windows Communication Foundation Service)

目錄:WCF 自訂使用者帳號/密碼篇

 

之前偶爾使用WCF﹐也只是將它當做原本ASP.NET傳統的Web service(ASMX web service)使用﹐並沒有實際去了解WCF和web service的區別﹐也不曾去深入為什麼要使用WCF。最近想把web service加上使用者驗證﹐打算採用SOAP Header的方式﹐這才好好的看了一下WCF和web service的不同﹐發現光安全性上就有許多的差異性。這次的筆記主要是在WCF自訂使用者認證﹐不過同時把研究過程中得到的知識一併記錄下來。

WCF提供有多種的認證技術﹐Windows認證﹑X.509憑證﹑使用者帳號/密碼認證...等。以現行的生態都是跨平台系統﹐因此Windows認證方式並不是很適合﹐因此選用自訂使用者帳號/密碼的認證方式。

 

1. Web服務(ASMX Web Service)與WCF服務(Windows Communication Foundation Service)比較

微軟在ASP.NET 1.0就開始支援Web Service﹐並且微軟所提供的Web Service加上IIS在開發上與使用上非常便利﹐WCF相對起來就有比較多的眉角和門檻。現今web service仍是許多ASP.NET開發者所使用﹐那麼為什麼要有WCF?WCF是不是可以完全取代web service?有一篇討論寫的不錯﹐可以參考一下。(http://social.msdn.microsoft.com/Forums/zh-CN/wcfzhchs/thread/c06420d1-69ba-4aa6-abe5-242e3213b68f)

微軟於.Net 3.0時開始導入WCF﹐希望能讓開發人員逐步取代原有的Web服務開發﹐然而在推出.Net 4.0開始 visual studio 2010其預設的網站專案中已見不到Web服務(但並非消失)﹐因為WCF的推出﹐微軟將Web Service的發展重心移到WCF上﹐原有的ASP.NET Web Service給了另一個名稱ASMX Web Service﹐那麼原有的Web服務與WCF到底有什麼不同﹐為什麼微軟希望用WCF來取代Web服務。

 

Web服務

WCF服務

.Net 版本

1.1或更高版本

3.5或更高版本

功能

必須安裝WSE之後才比較完整支援WS-*

完整﹐本身已實作WS-*的功能。

安全性控管

彈性﹐可單獨一個網站﹐也可直接建置於已存在的網站中。

彈性﹐可單獨一個網站﹐也可直接建置於已存在的網站中。

什麼是WS-*規格﹐WS-*是許多的Web服務相關的規範﹐由不同的標準組織或機構來維護和支持。不同的標準或互相補充﹐或重疊﹑或互相競爭。這些規範沒有公認的統一所屬機構﹐因為都是以WS-為開頭﹐統稱WS-*。這些Web服務規範通常都是難以實作的部分﹐比較重要的像是以下的規格

WS-Security

描述了如何將簽名和加密頭加入SOAP消息﹐如何在訊息中加入token。亦即與身份驗証有關﹐及加密簽章的處理。

WS-ReliableMessaging

可靠消息模型﹐確保訊息至少一次﹐至多一次﹐正好一次。

WS-Addressing

實際包含兩個新概念:端點引用(endpoint reference, EPR)和SOAP結構的消息資訊(message information, MI)頭。

WS-Trust

對WS-Security規範的一些擴充﹐專門處理有關安全tokens的發佈﹐整新和驗証﹐確保各方參與者的相互操作在一個可信任的安全資料交換環境中。

WS-Federation

跨網域單點登錄認証

WS-AtomicTransaction

一種互通的交易通訊協定﹐做為異質平台﹑跨internet的分散式交易。

WS-*的規範除了上述提到的之外﹐仍陸續增加當中。ASP.NET Web服務本身不支援WS-*﹐必須加裝WSE﹐才能支援。目前可以安裝的WSE最新版本為WSE 3.0 (http://www.microsoft.com/download/en/details.aspx?id=14089)﹐WSE 3.0後續並不會再增加和更新﹐也就是WSE 3.0是末代版本﹐微軟希望未來大家改用WCF開發。WCF已實作WS-*的規格﹐功能性比Web服務完整。WCF所支援的WS-*的通訊協定﹐可參考http://msdn.microsoft.com/zh-tw/library/ms730294.aspxhttp://msdn.microsoft.com/zh-tw/library/ms730879.aspx﹐的資料。

 

微軟除了Web服務與WCF服務﹐另外還有WCF RIA Service與WCF資料服務的伺服器端服務。

WCF RIA Service

.Net 3.5以上版本支援

Silverlight專用﹐可用於Silverlight網頁與Windows Phone 7.x。

WCF資料服務

.Net 3.5以上版本支援

前身為ADO.NET Data Service﹐不過與ADO.NET完全無關。

可以提供服務也可以提供資料模型﹐內建REST ful介面。

只可以使用ADO.NET實體資料模型。

參考資料:

WS-Security維基百科(http://zh.wikipedia.org/wiki/WS-Security)

WS-ReliableMessaging維基百科(http://zh.wikipedia.org/wiki/WS-ReliableMessaging)

WS-Addressing 維基百科(http://zh.wikipedia.org/wiki/WS-Addressing)

WS-Addressing對SOAP的隱式影嚮(http://www.ibm.com/developerworks/cn/webservices/ws-address.html)

WS-Trust和WS-SecureConversation (http://www.ibm.com/developerworks/cn/java/j-jws15/index.html)

WS-Federation維基百科(http://en.wikipedia.org/wiki/WS-Federation)

WS-AtomicTransaction (http://docs.oasis-open.org/ws-tx/wstx-wsat-1.1-spec-errata-os/wstx-wsat-1.1-spec-errata-os.html)

Web服務規範列表 維基百科(http://zh.wikipedia.org/wiki/Web%E6%9C%8D%E5%8A%A1%E8%A7%84%E8%8C%83%E5%88%97%E8%A1%A8)

 

2. Web服務與WCF服務建置上的差異

2.1 Web服務的建立

在vs 2003﹑vs2005﹑vs2008﹐Web 服務的建置都是單獨的專案﹐建立時就是獨立的網站。由Visual Studio開發工具的功能表選擇【檔案】à【新增】à【網站】﹐在新網站中選擇【ASP.NET Web服務】﹐決定好要建立位置(網站)﹐即可建立一個Web 服務的專案。

image

image

Visual Studio 2010在建立Web服務就有一些不一樣﹐如果依上述【檔案】》【新增】》【網站】﹐會發現找不到ASP.NET Web服務。在VS 2010(.Net 4.0) 預設是沒有Web 服務﹐基本上微軟就是希望大家改用WCF﹐但並非Web服務不見了﹐在.Net 4.0 Web 服務已不是獨立專案方式存在﹐而是依付於一個網站專案之下。

image

因此在vs2010使用.Net Framework 4之下要使用web服務是要先建立一個ASP.NET 網站﹐然後在方案總案中再以【加入新項目】的方式﹐即可找到Web服務的項目﹐加入後跟過去Web服務完全一樣。

image

image

如果在vs 2010中仍想像以前建立ASP.NET Web服務的專案﹐那麼在一開始建立網站專案時﹐則要選擇.Net Framework為2.0﹑3.0或3.5﹐則在專案範本中一樣有ASP.NET Web服務專案可以選。

image

 

2.2 WCF服務的建立

Vs 2008﹑vs 2010由【檔案】à【新增】à【網站】選取WCF服務即可建立一個WCF服務的專案。

image

不過﹐這不是唯一的建置WCF服務的方式。上述的建立方式是直接以IIS做為WCF的載具﹐這是個快速做法﹐實作上WCF不限定使用IIS做為載具﹐也可以自行撰寫載具WinForm﹑Windows服務做為WCF載具都可以。

由【檔案】à【新增】à【專案】左側選取WCF﹐中間選擇「WCF服務程式庫」。這一種方式在建置後會是一個DLL檔案﹐之後不論是WinForm﹑Windows服務或者IIS都可以當作WCF載具﹐引用WCF服務程式庫提供服務。

image

若是使用VS 2005的會比較麻煩一點(應該是麻煩很多點….v_v)。

WCF是在.Net 3.0時加入﹐建議要開發WCF還是使用VS 2008以上的版本才會方便﹐現在.Net Framework都己到了4.0了﹐相對的WCF也有一些改進。

 

3. WCF的繫結(basicHttpBinding & wsHttpBinding)

WCF提供了許多種服務繫結(binding)方式﹐其中basicHttpBinding﹑wsHttpBinding和NetTcpBinding是最常被使用的。NetTcpBinding是微軟最徍化﹐效率最高的﹐如果兩端都是微軟的solution﹐可以考慮NetTcpBinding﹐不過這不是這次想研究的。

basicHttpBinding﹐微軟在MSDN上的描述﹐BasicHttpBinding 使用 HTTP 做為傳送 SOAP 1.1 訊息的傳輸。服務可使用這個繫結公開符合 WS-I BP 1.1 的端點,例如 ASMX 用戶端取用的端點。同樣地,用戶端可使用 BasicHttpBinding 與公開符合 WS-I BP 1.1 之端點的服務通訊,例如 ASMX Web 服務或使用 BasicHttpBinding 設定的服務。安全性預設是關閉的,但是可以透過將 <basicHttpBinding> 的 <security> 子項目的模式屬性設定為非 None 的值,來新增安全性設定。根據預設,它使用「文字」訊息編碼和 UTF-8 文字編碼。

wsHttpBinding﹐MSDN上的描述﹐類似 BasicHttpBinding,不過提供更多的 Web 服務功能。它使用 HTTP 傳輸並提供訊息安全性,如同 BasicHttpBinding﹐為非雙工服務合約定義安全、可靠且互通的繫結。此繫結會實作下列規格:WS-Reliable 訊息用於可靠性以及 WS-Security 用於訊息安全性和驗證。傳輸是 HTTP,而訊息編碼是 Text/XML 編碼。

文字硬綁綁﹐直接看一下差異性﹐寫一段程式碼﹐不加其他的設定由Fiddler觀看封包的資料。這裏我先建置了一個WCF程式庫(MyProducts.lib)﹐後續的範例都是引用這一個程式庫。WCF有個好處﹐一份程式寫好後﹐後續要使用那一種載具提供服務或者要變換繫結﹐程式可以不用動﹐只要在設定檔上做手腳就可以了。

在MyProducts.lib中提供了一個方法SaySomething﹐只是要測試參數傳入﹐與資料回傳。

public string SaySomething(string value) {

return "You say [" + value + "].";

}

使用basicHttpBinding和wsHttpBinding呼叫同一個method

basicHttpBinding Request

image

basicHttpBinding Response

image

wsHttpBinding Request

image

wsHttpBinding Response

image

由封包資料可以看出﹐basicHttpBinding在預設值之下資料的傳遞都是明碼﹐這和ASP.NET 的ASMX Web Service是相同的﹐而wsHttpBinding的資料傳遞都是密文方式﹐這是wsHttpBinding預設安全性就是Message實作了WS-Reliable 訊息用於可靠性以及 WS-Security 用於訊息安全性和驗證。

basicHttpBinding和wsHttpBinding兩者只透過設定就可達到不同的效果﹐開發者不用為了如何對資料在傳遞過程加減密傷腦筯﹐basicHttpBinding也可以透過設定就讓傳遞的資料也加密﹐它只是預設不開啟而已。但﹐WCF的設定很多樣﹐對於開發者而言是另一項頭痛的地方。

看看以下兩者的設定檔﹐差別僅在於繫結(binding)不同﹐沒有動到任何的程式碼就可以達到不同的結果。

basicHttpBinding


  <system.serviceModel>
    <services>
      <service behaviorConfiguration="Products.Behavior" name="MyProducts.lib.ProductService">
        <endpoint binding="basicHttpBinding" contract="MyProducts.lib.IProductService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Products.Behavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

wsHttpBinding


  <system.serviceModel>
    <services>
      <service behaviorConfiguration="Product.Behavior" name="MyProducts.lib.ProductService">
        <endpoint binding="wsHttpBinding" contract="MyProducts.lib.IProductService" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Product.Behavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

 

參考資料:

WCF系統提供的繫結(http://msdn.microsoft.com/zh-tw/library/ms730879(v=vs.90).aspx)