本文轉自:http://book.51cto.com/art/200906/129770.htmweb
http://yeweiyun868.blog.163.com/blog/static/563784432011112985215397/數據庫
7.9.2 採用SSL實現加密傳輸(1)編程
在默認狀況下,IIS使用HTTP協議以明文形式傳輸數據,Web Service就是使用HTTP協議進行數據傳輸的。Web Service傳輸的數據是XML格式的明文。沒有采起任何加密措施,用戶的重要數據很容易被竊取,如何才能保護網絡中傳遞的這些重要數據呢?瀏覽器
SSL(Security Socket Layer)的中文全稱是加密套接字協議層,它位於HTTP協議層和TCP協議層之間,用於創建用戶與服務器之間的加密通訊,確保所傳遞信息的安全性,同時SSL安全機制是依靠數字證書來實現的。安全
SSL基於公用密鑰和私人密鑰,用戶使用公用密鑰來加密數據,但解密數據必須使用相應的私人密鑰。使用SSL安全機制的通訊過程以下:用戶與IIS服務器創建鏈接後,服務器會把數字證書與公用密鑰發送給用戶,用戶端生成會話密鑰,並用公共密鑰對會話密鑰進行加密,而後傳遞給服務器,服務器端用私人密鑰進行解密,這樣,用戶端和服務器端就創建了一條安全通道,只有SSL容許的用戶才能與IIS服務器進行通訊。
注 意 SSL網站不一樣於通常的Web站點,它使用的是"HTTPS"協議,而不是普通的"HTTP"協議。所以它的URL(統一資源定位器)格式爲"https://網站域名"。服務器
下面講解如何使用SSL來加強IIS服務器和Web Service的通訊安全。網絡
實現步驟以下。tcp
1.爲服務器安裝證書服務分佈式
要想使用SSL安全機制功能,首先必須爲Windows Server 2003系統安裝證書服務。進入"控制面板",運行"添加或刪除程序",接着進入"Windows組件嚮導"對話框,如圖7-13所示。工具
![]() |
圖7-13 Windows組件嚮導 |
勾選"證書服務"選項,單擊"下一步"按鈕。
接着選擇CA類型。這裏選擇"獨立根CA"選項,如圖7-14所示。單擊"下一步"按鈕,爲本身的CA服務器起名,並設置證書的有效期限,如圖7-15所示。
![]() |
圖7-14 選擇CA類型 |
![]() |
圖7-15 設置CA信息 |
最後指定證書數據庫和證書數據庫日誌的位置,如圖7-16所示,單擊"下一步"按鈕。
![]() |
圖7-16 指定證書數據庫 |
由於須要複製系統文件,因此須要插入Windows的安裝光盤,如圖7-17所示。安裝證書服務須要中止當前的IIS運行,因此要單擊"是"按鈕。
![]() |
圖7-17 複製系統文件 |
最後,顯示完成了證書服務的安裝,單擊"完成"按鈕,如圖7-18所示。
![]() |
圖7-18 安裝完成 |
7.9.2 採用SSL實現加密傳輸(2)
2.配置SSL網站
1)建立請求證書文件
要想讓Web Service使用SSL安全機制,首先需將Web Service配置爲網站。而後爲該網站建立請求證書文件。
依次單擊"控制面板"→"管理工具"按鈕,運行"Internet 信息服務(IIS)管理器",在管理器窗口中展開"網站"目錄,用鼠標右鍵單擊要使用SSL的Web Service網站,在彈出的快捷菜單中選擇"屬性"命令,在網站屬性對話框中切換到"目錄安全性"選項卡,如圖7-19所示,
![]() |
圖7-19 網站屬性 |
而後單擊"服務器證書"按鈕,彈出"IIS證書嚮導"對話框。
在"IIS證書嚮導"對話框中選擇"新建證書"選項,單擊"下一步"按鈕,如圖7-20所示。
![]() |
圖7-20 服務器證書 |
選擇"如今準備證書請求,但稍後發送"選項。單擊"下一步"按鈕,如圖7-21所示。
![]() |
圖7-21 證書嚮導 |
在"名稱"輸入框中爲該證書取名,而後在"位長"下拉列表中選擇密鑰的位長(默認爲1024,長度越長保密性越好,但性能會越差)。單擊"下一步"按鈕,如圖7-22所示。
![]() |
圖7-22 設置證書名稱 |
設置單位信息,如圖7-23所示,而後單擊"下一步"按鈕。設置公共名稱,如圖7-24所示。
![]() |
圖7-23 設置單位信息 |
![]() |
圖7-24 設置公共名稱 |
注 意 公共名稱必須輸入爲訪問站點的域名,例如要想用地址https://www.maticsoft.com訪問Web Service,則此處必須填寫爲"www.maticsoft.com",不然將提示使用了不安全的證書,致使站點沒法訪問。而且切記,www.maticsoft.com和www.maticsoft.com:8001 帶端口的訪問也是不一樣的,若是設置的是www.maticsoft.com,則網站設置爲www.maticsoft.com:8001來訪問也是沒法使用的。
而後,單擊"下一步"按鈕,設置國家地區,如圖7-25所示。
![]() |
圖7-25 設置國家地區 |
設置證書的單位、部門、站點公用名稱和地理信息,一路單擊"下一步"按鈕。
最後指定請求證書文件的保存位置。這樣就完成了請求證書文件的建立。
7.9.2 採用SSL實現加密傳輸(3)
2)申請服務器證書
完成上述設置後,還要把建立的請求證書文件提交給證書服務器。
在服務器端的IE瀏覽器地址欄中輸入"http://localhost/CertSrv/default.asp"。
在"Microsoft 證書服務"歡迎窗口中單擊"申請一個證書"連接,如圖7-26所示。
接下來在證書申請類型中單擊"高級證書申請"連接,如圖7-27所示。
![]() |
圖7-26 申請證書 |
![]() |
圖7-27 選擇證書類型 |
而後在高級證書申請窗口中單擊"使用base64編碼的CMC或PKCS#10……"連接,如圖7-28所示。
![]() |
圖7-28 選擇編碼 |
接下來在新打開的窗口中,打開剛剛生成的"certreq.txt"文件,將其中的內容複製到"保存的申請"中,如圖7-29所示。
![]() |
圖7-29 提交證書申請 |
單擊"提交"按鈕,顯示"證書掛起"頁面,如圖7-30所示。
![]() |
圖7-30 證書掛起 |
7.9.2 採用SSL實現加密傳輸(4)
3)頒發服務器證書
提交證書申請之後,還須要頒發服務器證書。依次選擇"開始"→"設置"→"控制面板",雙擊"管理工具",再雙擊"證書頒發機構",在打開的對話框中選擇"掛起的申請"選項,如圖7-31所示。
![]() |
(點擊查看大圖)圖7-31 掛起的申請 |
找到剛纔申請的證書,而後用鼠標右鍵單擊該項,在彈出的快捷菜單中選擇"全部任務"→"頒發"命令,如圖7-32所示。
頒發成功後,選擇"頒發的證書"選項,雙擊剛纔頒發的證書,在彈出的"證書"對話框中的"詳細信息"標籤頁中,單擊"複製到文件"按鈕,如圖7-33所示。
![]() |
圖7-32 頒發證書 |
![]() |
圖7-33 複製到文件 |
彈出"證書導出嚮導"對話框,連續單擊"下一步"按鈕,選擇"Base64編碼X.509"選項,如圖7-34所示。
![]() |
(點擊查看大圖)圖7-34 選擇導出文件格式 |
單擊"下一步"按鈕,並在"要導出的文件"對話框中指定文件名,最後單擊"完成"按鈕。
4)安裝Web服務器證書
從新進入IIS管理器的"目錄安全性"標籤頁,單擊"服務器證書"按鈕,彈出"掛起的證書請求"對話框,選擇"處理掛起的請求並安裝證書"選項,單擊"下一步"按鈕,如圖7-35所示。
![]() |
(點擊查看大圖)圖7-35 處理掛起的證書 |
指定剛纔導出的服務器證書文件的位置,如圖7-36所示。
![]() |
(點擊查看大圖)圖7-36 選擇導出位置 |
接着設置SSL端口,使用默認的"443"便可,最後單擊"完成"按鈕。
7.9.2 採用SSL實現加密傳輸(5)
5)配置網站啓用SSL通道
在網站屬性"目錄安全性"標籤頁中單擊安全通訊欄的"編輯"按鈕,而後,勾選"要求安全通道(SSL)"選項,如圖7-37所示。
![]() |
(點擊查看大圖)圖7-37 啓用網站SSL通道 |
忽略客戶端證書:選擇該選項能夠容許用戶沒必要提供客戶端證書就可訪問該站點。
接受客戶端證書:選擇該選項能夠容許具備客戶端證書的用戶進行訪問,證書不是必需的。具備客戶端證書的用戶能夠被映射;沒有客戶端證書的用戶可使用其餘身份驗證方法。
要求客戶端證書:選擇該選項則僅容許具備有效客戶端證書的用戶進行鏈接。沒有有效客戶端證書的用戶被拒絕訪問該站點。選擇該選項從而在要求客戶端證書前,必須選擇"要求安全通道(SSL)"選項。
最後單擊"肯定"按鈕,即完成啓用SSL了。在完成了對SSL網站的配置後,用戶只要在IE瀏覽器中輸入"https://網站域名"就能訪問該網站。
注 意
勾選上SSL後,必須用HTTPS來訪問,而訪問網站的端口也會使用SSL端口,默認爲443。
若是在你訪問站點的過程當中出現沒法正常訪問的狀況,那麼請檢查服務器防火牆是否禁止對SSl端口443的訪問,這點比較容易被忽視,固然你也能夠本身修改端口。
若是仍是不能訪問,出現提示"你試圖從目錄中執行 CGI、ISAPI 或其餘可執行程序,但該目錄不容許執行程序。HTTP錯誤403.1-禁止訪問:執行訪問被拒絕。"那麼請檢查網站主目錄的執行權限,將執行權限設置爲純腳本便可,如圖7-38所示。
![]() |
圖7-38 設置執行權限 |
6)客戶端安裝證書
若是IIS服務器設置了"要求客戶端證書",則其餘機器或用戶想經過HTTPS訪問和調用該Web服務,就須要將CA的根證書導入到客戶端證書的可信任機構中,客戶端才能夠正常訪問Web服務。
(1)選擇"開始"→"運行"命令,在彈出的對話框中輸入"mmc",出現如圖7-39所示的界面。
![]() |
圖7-39 啓動控制檯 |
(2)選擇"文件"→"添加/刪除管理單元"命令,出現如圖7-40所示的界面。
![]() |
圖7-40 添加/刪除管理單元 |
(3)單擊"添加"按鈕,在可用獨立管理單元列表中選擇"證書"選項,出現如圖7-41所示的界面。
(4)選擇"計算機帳戶"選項,單擊"下一步"按鈕,選擇"本地計算機"選項,而後依次單擊"完成"→"關閉"→"肯定"按鈕。
![]() |
圖7-41 添加證書管理單元 |
進入當前用戶的證書管理單元,界面如圖7-42所示。
![]() |
(點擊查看大圖)圖7-42 選擇證書導入位置 |
選中"我的"下的"證書節點"選項,單擊鼠標右鍵,在彈出的快捷菜單中選擇"全部任務"→"導入"命令,如圖7-43所示。
![]() |
(點擊查看大圖)圖7-43 導入證書 |
選擇咱們剛纔頒發的服務器證書cert.cer,將其導入到我的的存儲位置,導入後如圖7-44所示。
![]() |
(點擊查看大圖)圖7-44 導入到證書 |
7)SSL的優勢與缺點
優勢:它對Web服務提供的數據完整性沒有任何影響,當值返回給客戶時,值仍是保持原樣,並無因在傳輸過程當中使用了加密技術而發生變化。
缺點:它對站點的總體性能有影響,由於它須要進行不少加解密的數據處理。
7.9.3 訪問IP限制
除了以上兩種方式之外,還有一種比較簡單的驗證方式,就是經過對來源IP的檢查來進行驗證,咱們只容許指定IP的服務器來訪問,保證點對點的安全,咱們能夠在Web Service的方法中加入對IP的檢查。
(示例位置:光盤\code\ch07\WebService1)
bool ValidateIP(int UserID, out string exceptionInfo)
{
exceptionInfo = "";
string uip = HttpContext.Current.Request.UserHostAddress;
Common dal = new Common();
List<string> ips = dal.GetPermitIp(UserID);//獲得該用戶ID所容許的IP列表
if (ips == null || ips.Count == 0)
{
exceptionInfo = "調用Web服務的客戶端IP未被容許,沒法訪問!";
return false;
}
if (ips.Contains(uip)) //容許IP列表中包含該IP
{
return true;
}
exceptionInfo = "調用Web服務的客戶端IP未被容許,沒法訪問!";
return false;
}
在具體Web方法裏調用該方法檢查用戶訪問者是不是以咱們容許的IP進行訪問的,以確保安全。
優勢:簡單,防止非指定客戶機器訪問。
缺點:IP是能夠僞造的;維護IP地址表比較煩瑣。且只適合於固定IP訪問者的狀況。
總之,上面幾種方式只是一個簡單的示例,講解了怎樣經過編程和配置的方式拒絕沒有合法驗證單據的客戶端訪問Web Service來保護你的Web Service。在你的安全模型中要求的複雜級別應該由你的商業需求決定。能夠是一種或幾種驗證機制的組合。固然並非全部的Web應用程序都須要上面的安全模式,尤爲是當你的Web Service能夠自由使用的時候,並不須要上面的安全機制處理。
7.10 Web Service開發中須要注意的問題(1)
1.接口是自說明的
接口的名字、參數和返回值應該一看就知道這接口大概是幹什麼用的。固然接口描述文檔確定是必需的,但這些描述文檔的質量誰知道怎麼樣呢,誰有空每天翻着文檔寫東西呢,又有誰會背下來呢?因此讓人眼前一亮的接口命名絕對值得,這也是全部代碼書會告訴你應該遵照的一條規則。
2.服務接口粒度要合適
Web Service服務接口粒度過小了,那純粹是不考慮XML解析性能了。通常新手容易犯這毛病,簡單地把類的方法暴露出來作服務接口,這樣實際上是把原來在 local的調用放到了remote,除此以外幾乎沒有任何好處。粒度太大,會給使用者帶來不少麻煩,由於在Web Service中,粒度很大的服務通常都須要不少參數來映射該服務各類各樣的狀況。
3.接口參數要儘可能簡單
只有一個參數的服務接口,每每不能知足業務需求。但過多的參數也提升了出錯的概率,增長了測試的成本。因此,參數恰到好處爲妙。
4.要提供對接口參數和返回值的校驗
嚴格來講,對接口參數和返回值的驗證也應該算是Web Service接口聲明的一部分。增長對參數和返回值的校驗,有利於減小調用者的疑惑,系統接受什麼樣的參數,返回值是什麼格式都一目瞭然。可是這須要一個很好的權衡,不然調用者會以爲你暴露的方法很難用,由於限制太多了。比較理想的系統應該是寬進嚴出的,目標用戶越多越應該注意這一點。要在寬進嚴出和全面校驗之間作好平衡確實挺難的。簡單的辦法是,對要暴露的接口本身作測試,在測試的過程當中體會這個度。通常來講若是本身感受都不爽,那別人是絕對不會用的。
5.接口的返回值應該是簡單的語言無關的
聽見過不少人問如何返回DataSet之類的複雜類型,尤爲是玩.NET的人,也許是VS.NET對封裝DataSet提供了過於完美的支持吧。但對於XML來講,把任何複雜對象映射到XML文檔都是困難的。就比如把三維向二維投影同樣,複雜性增長了可不是一點半點。在XML中說到底全部的類型都是字符串,要想表達其餘類型,就要添加額外的說明。能夠看看rpc/encode方式WSDL文檔的complexType部分,自行體會。
6.謹慎地拋出異常
對Web Service中的任何異常都應該進行相應的處理。能夠簡單地概括爲如下兩種狀況。
第1種狀況是接口返回值是簡單類型,好比bool型,就true和false兩種狀況,不拋出異常怎麼辦?選擇有兩種,一是拋出異常,二是改變接口,返回int用1和0對應true和false,用-1對應系統異常。
第2種狀況是接口返回值是複雜對象,能夠經過參數out string exceptionInfo來返回異常信息。
7.接口要儘可能採用更新的標準
如何讓一次定義的接口能服務得更好更久?從技術規範方面來講有兩點:不超前,不落伍。超前,支持它的工具集不會太豐富,估計誰也不想弄出個看起來很美可是誰都用不了的東西;落伍,眼前全部的工具大概都支持,不過明天就不必定了,技術發展這麼快,不能把本身累死吧。儘可能採用更新的標準的意思是在不落伍的基礎上要有前瞻性。舉個簡單的例子,今天再採用rpc/encode方式就顯得不合時宜了,雖然它在前兩年很流行,可今天都已經不提倡用了,明天說不定你們就都忘了。就算你及時更新了你的接口,客戶也說不定已經換了供應商了。
8.要注意標準的通用性
雖然都是同樣的標準,但標準有不一樣的版本,並且即便是同一個版本的標準,不一樣的工具實現起來也仍是有細微差異的。若是用戶是特定的還好說,採用些工具綁定的特性也沒什麼。但若是接口用戶不是特定的人羣,那就要注意了,在採用某一規範標準時不要用實現工具所特有的東西,不然頗有可能形成客戶的麻煩,致使只有不多一部分客戶能使用你提供的接口。多一個客戶就多一分錢啊,兄弟,幹嗎跟錢過不去?
9.禁用HTTP POST/GET協議
除非另外指定,不然.NET將試圖把Web服務綁定到3種協議:HTTP/POST、HTTP/GET和SOAP。之因此說"試圖",是由於依賴於服務的參數和返回類型,HTTP/GET協議可能不可用。.NET生成的WSDL文件將自動包含綁定這3種協議的指令,客戶程序能夠自由選擇使用哪一種協議與服務通訊。
只要在Web.config文件中加入下列內容,就能夠刪除對HTTP/POST和HTTP/GET協議的綁定:
<webServices>
<protocols>
<remove name="HttpPost" />
<remove name="HttpGet" />
</protocols>
</webServices>
爲何要避免經過HTTP/POST和HTTP/GET協議引出Web服務呢?主要的2個因素是安全性和互操做性。HTTP/GET的安全性不如SOAP,並且因爲HTTP/GET常見於Web連接,懷有惡意的人可能利用它實施欺騙,使別人在不知不覺中用本身的安全標識調用Web服務,卻還覺得本身在單擊Web連接。
就互操做性而言,SOAP是普遍應用的Web服務通訊標準,而HTTP/GET和HTTP/POST不是。所以,對於.NET生成的WSDL文檔中默認包含的HTTP/GET和HTTP/POST綁定,許多自動生成代理服務器的工具不會理解。所以,若是你的Web服務不是非綁定到HTTP/GET和HTTP/POST協議不可,最好取消這兩種綁定。
7.10 Web Service開發中須要注意的問題(2)
10.用TcpTrace查看SOAP請求/應答消息
對於開發Web服務應用的人來講,調試多是件異乎尋常的難事,由於不管是.NET SDK仍是VS.NET,都沒有提供工具來查看客戶端和服務器之間的SOAP消息。
若是.NET和非.NET的客戶端、服務器端的交互過程出現了問題,要想找出問題的根源,擁有查看SOAP消息的能力就尤其重要,由於這類問題每每與SOAP消息的格式有關(例如"消息中包含了SOAPAction嗎?")。
tcpTrace(www.pocketsoap.com/tcptrace)是一個查看這類消息交換過程的優秀工具,它經過設置一個客戶端和服務器端之間的隧道工做。啓動tcpTrace時,它會要求輸入目標URL和端口號,以及tcpTrace監聽的本地端口號。這樣,你就能夠經過設置代理stub的URL屬性,把stub指向這個本地端口(例如localhost:8080)。tcpTrace可以記錄全部的請求和應答HTTP消息。
tcpTrace的一個侷限是,它在消息流程中所處的位置決定了它不能用來查看經過SSL發送的消息。若是你要查看經過SSL發送的SOAP消息,只能編寫一個定製的ISAPI過濾器。
11.簡化接口設計
在衆多有關N-層應用設計的論述中,簡化接口設計這一設計要訣能夠說是隨處可見。可是,對於Web服務這樣的分佈式計算環境來講,簡化接口設計的重要性更加突出。
在設計分佈式應用時,出於性能和可伸縮性的考慮,應當保證客戶端和服務器端之間的調用盡量地少。減小網絡調用不只有利於減小通訊開銷(若是隻用1個SOAP消息能夠達到目標,就絕對不要發3個消息),下降網絡流量,並且提升了應用的性能。顯然,這一切都是開發者求之不得的目標。那麼簡化的接口到底有何特徵呢?
首先來看一個複雜接口的例子:
namespace ChattyService
{
public class ChattyService : WebService
{
private string username;
private string password;
public string Username
{
[WebMethod]
set
{
username = Username;
}
}
public string Password
{
[WebMethod]
set
{
password = Password;
}
}
[WebMethod]
public bool Logon()
{
//驗證身份
return true;
}
}
}
在這個例子中,username和password是兩個屬性,調用logon()方法以前首先必須設置這兩個屬性。有一個問題光看這段代碼不太容易注意到,這就是username和password都做爲Web方法引出。這就是說,每次對屬性的get/set操做都會致使一個對服務的調用。
按照簡化接口設計的要求,改進後的代碼以下:
namespace ChattyService
{
public class ChattyService : WebService
{
[WebMethod]
public bool Logon(string Username, string Password)
{
//驗證身份
return true;
}
}
}
如今,username和password成了logon()方法的參數。修改以後的代碼的優勢在於,它把登陸操做對服務器的3次調用下降到了1次。另外一方面,若是參數的個數太多,這個方法可能看起來很不像樣。這時,可能要把方法的參數整理成幾個複雜類型,例如,把username和password 兩個參數封裝到一個credential(證書)對象中。
12.避免使用ASP.NET會話狀態
.NET實現的會話狀態管理功能解決了它的前輩ASP 3.0存在的許多問題,例如請求串行化等,但仍存在一些侷限。應當認識到,.NET的會話狀態管理功能不是專門爲Web服務環境中的會話狀態而設計的,而是爲了在範圍更普遍的ASP.NET應用中管理會話狀態而設計的,它依賴於HTTP Cookie(有一種經過改寫URL實現的不須要Cookie的模式,但不適用於Web服務)。
Cookie是HTTP獨有的。在Web上,全部的瀏覽器都支持HTTP,因此Cookie很是適合在Web應用中使用。可是,在Web服務中應用Cookie卻把服務限定到了HTTP協議上。另外一方面,SOAP協議的運行是獨立於傳輸協議的,所以若是把Web服務應用限制到HTTP協議上,那麼應用的靈活性也將受到限制,一旦要經過非HTTP的傳輸協議(例如SMTP)提供服務,事情就會變得很麻煩。