[ASP.NET的二三事] Lesson 7 ASP.NET的XML Web服務模型(Web Service)
在過去,在不同的環境下的伺服器、網域、或是資料格式,甚至是安全性的機制之間的應用程式若要相互溝通是一項挑戰
然而隨著Internet的發展,Web服務的出現就變成了一種普遍用於資料存取、分散式資料交換或是商業流程的運作模式。
Internet是透過支援的標準:包含了HTTP的協定以及XML格式來讓Web服務運作
然而,直接針對HTTP底層協定以及XML、還有SOAP(Simple Object Access Protocal)來進行程式開發,其實是有困難點(或是說耗時)的。
不過ASP.NET提供了一個建立與使用XML架構的WebService模型,使我們可以透過程式碼(C#或是VB)來定義我們的Web服務。
ASP.NET會將程式碼轉換成Web服務的物件,這個物件將會知道如何將Web服務公開出來(它會把底層細節處理掉)
這些細節包含了SOAP的請求過程、執行我們實作的.NET程式碼,並序列化我們請求服務後的結果,將其透過SOAP的協定送回請求端。
除此之外,ASP.NET會提供一個簡單的客戶端模型來供外界使用Web服務,在ASP.NET中使用Web服務的時候,可以加入Web服務參考。
接著Web服務會產生一個Proxy物件。這個時候我們就可以透過Proxy物件來撰寫我們客戶端的程式碼:
這個Proxy物件專注於序列化、SOAP訊息以及相關的流程服務。
ASP.NET的XML Web服務模式示圖:
當我們在設計Web服務的時候,要注意的是這個Web服務類別可能會被跨應用程式領域或是網路地呼叫。
而呼叫的訊息(包含回傳的訊息)會是透過HTTP協定傳輸,因此這些訊息必須被序列化(Serialized)以及反序列化(Deserialized)
這類型的呼叫會造成昂貴的處理時間,因此在這些服務被呼叫的時候必須考量自己的應用程式應該是何種需求:
一種是要處理大量的請求數量,並回傳的運算需求,另一種可能流程型處理需求,可以將流程寫在WS中來進行狀態保存或存取資料
(減少多個重覆、連續性的呼叫。
ASP.NET提供了System.Web.Services.WebService的類別包裝了底層實作WebService的細節:
而我們僅需要繼承上述WebService的類別,ASP.NET就會幫我們顧好好的。
在我們新增一個ASP.NET Web服務的專案後(或是我們可以在一般的站台中加入asmx的檔案)
ASP.NET會自動幫我們定義好asmx的檔案,這個檔案到時候也會直接發佈到服務站台中
asmx檔案可以揭露我們有哪些Web服務可以使用,其他我們可以想像就是一個Web站台的型式來管理Web服務。
(可以與其他網頁併存於站台,同時可以存取到Web.Config、App_Code、App_Data的資料)
因此外部也是透過URL來存取Web服務的asmx檔案。
ASP.NET讓撰寫Web服務就像是一般在寫應用程式的API一樣:
在asmx所搭配的asmx.cs檔案中(Code behind),你可以看到一個Web服務定義的方式如下(若要定義多個可以再加多個WebMethod)
1: [WebService(Namespace = "http://tempuri.org/")] //相關解說請見MSDN
2: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] //相關解說請見MSDN
3: [System.ComponentModel.ToolboxItem(false)] //相關解說請見MSDN
4: public class TestService : System.Web.Services.WebService
5: {
6: [WebMethod]
7: public string invokeSrv(string pXml)
8: {
9: string tResult = string.empty;
10: //呼叫其他的物件,就像平常寫程式一般
11: return tResult;
12: }
13: }
關於WebService的物件與使用語法,請進一步地參考http://msdn.microsoft.com/zh-tw/library/ba0z6a33.aspx
以上僅分享其運作原理
使用Web服務時
可以透過先前所說加入服務參考,讓我們的程式碼直接操作Proxy物件(這個原理就是代理人的DesignPattern)
或是我們也可以使用AJAX的機制,透過Client Script來呼叫WebService
前者僅需要在參考的目錄上選擇加入Web參考,接著輸入必要資訊就可以了
而後者需要參考以下的流程:
1.將WebService的類別上標示[System.Web.Script.Serivice.ScriptService]
2.在Web.Config中註冊ScriptHandlerFactory的handler
3.客戶端程式新增一個ScriptManager,並加入服務參考(註明Path = “xxxx.asmx”)
4.撰寫Java Script的語法,並呼叫Web服務的方法,並指定對應的流程(例如將值回填入特定的Input控件)
5.將JavaScript語法註冊到特定的控件的ClientScript的屬性。(例如OnClick)
最後,在使用Web服務的時候,XML Web服務有兩個安全性的機制可供選擇:
其一是透過ASP.NET的認證機制,這個機制就像是在Web中瀏覽目錄、網頁、資料夾一樣。
另一個是我們可以自己寫SOAP的Header的安全性機制。這提供了無法使用ASP.NET的認證機制的客戶端來使用
ASP.NET提供了多個Security的機制給XML的Web服務使用:
每個ASP.NET的安全性議題都要效能與安全性上做一個選擇,
例如假如我們針對敏感性資料(信用卡、身份證字號)我們可能會希望透過網路服務進行加密。
也因此會造成加解密時的效能降低,因此在有的時候,例如透過圖書號碼查詢書籍資料的網路服務
我們就希望可以盡可能的開放,透過簡單的參數就可以快速地查詢資料,而不用透過許多的認證過程。
1.Windows Basic Authentication
將使用者的帳號與密碼透過文字傳到服務端。適合用於客戶端非Windows的狀況。
2.Windows Basic Authentication Over SSL
與1同,但是透過SSL協定,加密使用者的密碼,加解密時易造成效能上的影響。
3.Client Certificates
透過憑證來認證,其憑證來自於第三方、可信賴的單位來進行驗證,因此我們可以將憑證直接視別為被驗證過的使用者,來提供服務。
4.Windows Digest
類似 於1,但使用者的密碼在個機制下是透過hash加密過的。這個選項不要求SSL協定,但也要求服務雙端都是Windows。
5.Forms'-based authentication
這個機制不支援Web服務的認證機制。
6.Windows Integrated
要求客戶端與伺服器端都必須是Windows,這個安全機制會由客戶傳送加密的認證物件給伺服器端。
以上詳細的說明可參考”How to:Configure an XML Web Service for Windows Authentication”一文(MSDN)
若使用基本的認證機制,我們必須要另外建立NetworkCredentials的類別,並將名稱、密碼還有網域設定好。
接著建立CredentialCache物件來加入NetworkCredentials的物件。最後將這個Web服務物件中所產生Proxy的Credentials屬性
若使用的是整合式的安全機制,我們將Web服務Proxy的物件設定Credentials屬性為System.Net.CredentialCache.DefaultCredentials。
這樣Web伺服器在執行到Web網頁的時候,會同時將認證資訊自動傳給Web服務!
最後SOAP的Header可以讓我們自訂用於安全加密的資訊,並送到WebService
對於跨防火牆或是要傳遞資訊的情境下要傳遞未加密的資訊,SOAP Header 也是一個不錯的方案
而在伺服器端(服務提供者),我們可以透過IHttpModule的介面來取得SOAP的請求,並取得Header資訊、拆解(解密)
這個詳細的說明可參考”Perform Custom Authentication Using SOAP Headers”一文(MSDN)
參考資料:
MSDN
書籍的資料來源:MCTS for ASP.NET