繼《WCF分布式應用程序開發必備知識》系列之後,經過一周的時間,我准備了關於如何使用WSE3.0進行Web Service安全開發的文章--《WSE3.0構建Web服務安全》,寫出來一起與大家分享。《WCF分布式應用程序開發必備知識系列》第4節Web服務已經涉及到Web服務安全的問題。這個系列仍是對以前技術的整理和學習的文章。我在整理的過程中也收獲很多,對整個WSE3.0的安全機制有的新的認識。不管高手還是菜鳥,都希望你能從我的這個系列文章裡有所收獲。那麼我們就來一起學習這個系列文章的第一篇:WSE3.0安全機制與實例開發。
全部文章分為5個部分:
1.WSE3.0框架介紹
2.安全基本概念
3.下載與安裝
4.代碼實現與分析
5.總結。
網上很多參考的文章在介紹WSE安全開發的時候不夠系統。往往有文章沒代碼,或者有代碼但運行不了。最後我還會照例放出文章的例子代碼。並包括詳細的注釋。
下面我們進入今天的正式學習。
【1】.WSE3.0框架介紹
WSE3.0全稱是 Web Services Enhancements 3.0。是微軟針對Web Service推出的安全實現平台,包括為了實現安全認證和加密特定的類庫。WSE3.0的很多安全實現方式都能在WCF框架裡找到影子。WebSerivice 2.0 支持 WS-I Basic Profile 1.1 和 SOAP 1.2。這意味著,它支持 XML 1.0、XML 架構定義 (XSD)、Web 服務描述語言 (WSDL)、SOAP 1.1、SOAP 1.2 以及編譯時的基本配置文件一致性驗證。WSE 3.0 通過提供對某些更高級的 WS-* 協議的支持,來補充 WebSerivice 2.0 的功能。
因此我們通常會使用WSE 3.0增強 WebSerivice安全。WSE3.0經常使用的特性包括如下四個方面:
(1)基於消息的安全性 (WS-Security) :支持WS-* 協議
(2)高效的二進制數據傳輸 (MTOM) :消息傳輸優化機制Message Transmission Optimization Mechanism
(3)可選的宿主環境 (Host):多個宿主程序的實現,IIS外托管的支持
(4)自定義聲明性策略管道(Policy):根據用戶需要自定義策略
首先,WSE 3.0支持WS-* 協議。它是由IBM、Microsoft 和 Verisign 聯合發布,是關於 Web 服務安全性(Web Services Security,WS-Security)的規范,該規范提供了一套幫助 Web 服務開發者保護 SOAP 消息交換的機制。這個規范已經被 OASIS 所接受,並且新組建了 Web 服務技術委員會(Web Services Technical Committee,The WSS TC),以促使 WS-Security 成為開放標准。概念性協議棧規定了 Web 服務中構建安全性非常重要的額外元素。路線圖中新增的三個部分,策略層中的兩個元素和聯合層中的一個元素(如圖 所示)
各個層次的作用相輔相成。其中WS-Trust 通過定義一組接口開始了定義信任關系的工作,安全性令牌服務將為安全性令牌的發出、交換和驗證提供這組接口。它旨在支持創建多種安全性令牌格式,以適應各種認證和授權機制。發出安全性令牌服務接受一個輸入請求(通常還有身份證明),然後以指定的身份所請求的令牌(即一個特定的業務證書)作為響應。WS-Secure Conversantion 建立在以安全性令牌為基礎的信任這一概念之上。它描述了如何在策略定義的信任關系上下文中使用安全性令牌來使得多個服務請求者和服務提供者能在會話期間安全地交換信息。安全性空間內的這種預期行為的描述也可以稱之為信任策略,WS-Policy 框架支持信任伙伴表達和交換他們的信任聲明。WS-Trust 定義了整個信任關系的行為,而 WS-SecureConversation 則著重定義了安全通信的安全性上下文(安全性令牌)。
其次,基於消息的安全性和 消息傳輸優化機制MTOM 是人們在 Web Serivice項目中使用 WSE3.0 的兩個主要原因。另外WSE 3.0 通過Web Serivice提供的擴展來封裝對Web Serivice調用。這使我們就能夠利用各種 WSE 3.0 功能。在實際開發中我們只需要WSE 3.0設置工具並選擇所需的選項。就可以完成對項目的特定設置。這些信息會保存帶配置文件裡的對應位置。
再次,多宿主部署。使得我們可以靈活第部署和使用Web Service.而不是單單以來IIS來發布Web服務。WSE 3.0 使您能夠執行 Web Serivice類型的自定義宿主。消息處理類 SOAPSender 和 SOAPReceiver 使您能夠實現任何類型的高級消息處理模式。WSE 3.0 支持 HTTP 和 TCP協議。允許第三方插入自己的傳輸實現。
最後,在 Web Serivice項目中啟用 WSE 3.0 的另一個原因是,要利用它的策略管道擴展性模型。WSE 使您能夠插入對進入和離開終結點的 SOAP 消息執行預處理和後續處理的篩選器。該擴展點比 WebSerivice SOAPExtension 框架更易於使用,因為它提供的功能可以創建能夠與 WSE 提供的現有聲明性安全策略相結合的自定義聲明性策略。
另外還可以使用其提供的 SOAP 消息診斷跟蹤功能。
【2】.安全基本概念
介紹完WSE3.0的一些基本概念和特性。我們再來熟悉一下常見加密技術、密鑰和證書。
(1)加密技術,為什麼要使用加密技術,主要是為了實現一下目的:
a) 機密性。確保數據的保密性。機密性通常是使用加密實現的。可以使用加密算法(使用加密密鑰)將明文轉換為密文,並使用相應的解密算法將密文轉換回明文。對稱加密算法使用相同的密鑰進行加密和解密,而非對稱算法則使用公鑰/私鑰對。
b)數據完整性。確保數據免受意外或者故意(惡意)的修改。完整性通常是由消息身份驗證代碼或哈希值提供的。哈希值是從數據序列導出的固定長度的數值。哈希值用於驗證通過非安全通道傳送的數據的完整性。可以將收到的數據的哈希值與傳送時數據的哈希值進行比較,以確定數據是否被篡改。
c)身份驗證。保證數據來自某一方。數字證書用於提供身份驗證。數字簽名通常應用於哈希值,因為這些值比它們所代表的源數據小得多。
(2)密鑰和證書:
非對稱加密使用公鑰/私鑰對。對於使用私鑰加密的數據,只能使用相應的公鑰進行解密,反之亦然。(參考MSDN)
(3)簡單介紹一下常見的加密手段如下:
表 1: .NET Framework 為其提供現成實現類的算法。
對稱算法 非對稱算法 哈希算法
DES(數據加密標准)
DSA(數字簽名算法)
HMAC SHA1(使用 SHA1 哈希算法且基於哈希的消息身份驗證代碼)
TripleDES(三重數據加密標准)
RSA
MAC Triple DES(使用 Triple DES 的消息身份驗證代碼)
Rijndael
MD5
RC2
SHA1、SHA256、SHA384、SHA512(使用各種哈希大小的安全哈希算法)
a。私鑰加密算法:使用單個私鑰來加密和解密數據。由於具有密鑰的任意一方都可以使用該密鑰解密數據私鑰加密又稱為對稱加密,因為同一密鑰既用於加密又用於解密。私鑰加密並不能實現數據完整性,即防止數據被更改;也無法完成對身份的驗證,即確保數據發自特定的一方。.NET 提供以下實現類以提供對稱的密鑰加密算法:
b.共鑰加密:公鑰加密使用一個必須對未經授權的用戶保密的私鑰和一個可以對任何人公開的公鑰。公鑰和私鑰都在數學上相關聯;用公鑰加密的數據只能用私鑰解密,而用私鑰簽名的數據只能用公鑰驗證.NET 通過抽象基類 (System.Security.Crytography.AsymmetricAlgorithm) 提供下列非對稱(公鑰/私鑰)加密算法:
•
DSACryptoServiceProvider
•RSACryptoServiceProvider
c.哈希值:哈希算法將任意長度的二進制值映射為固定長度的較小二進制值,這個小的二進制值稱為哈希值。哈希值是一段數據唯一且極其緊湊的數值表示形式。.NET Framework 提供以下實現數字簽名算法的類:
NET 提供了下列哈希算法: •
SHA1、SHA256、SHA384、SHA512
•MD5
•HMACSHA(加密的哈希算法)
•MACTripleDES(加密的哈希算法
d.數字簽名:數字簽名驗證發送方的標識並保護數據的完整性。事實上數字簽名是基於以上各種加密技術組合的解決方案。一個基本的數字簽名方案可能有如下步驟:雙方各自生成一個公鑰/私鑰對。雙方交換他們的公鑰。雙方生成一個用於對稱加密法的私鑰,並使用該對稱私鑰加密要發送的消息。生成加密後消息的哈希值。用對方的共鑰加密對稱私鑰和哈希值(組合密文即為簽名),並將該簽名附加在消息主體的密文後發送給對方。
以上知識簡單的加密算法的簡單介紹,具體大家可以查看相關的安全和加密方面的書籍資料。這裡簡單介紹是為了更好第理解WSE3.0的安全機制的實現。
【3】.下載與安裝
下面來介紹一下WSE 3.0的下載和安裝情況。
(1)WSE 3.0下載地址。下載並安裝WSE 3.0,你可以選擇安裝Tools和Samples,開發環境選擇Visual Studio 2005插件方式,開發過程中配置Web服務WSE 3.0特性會比較方便。
安裝如圖:
一定要選擇插件方式,否則我們本地建立項目的時候看不到設置選擇下一步直到安裝完成。
(2)Visual Studio 2005 緊密集成
可以直接添加web服務引用Add Web Reference/Update Web Reference
可以進行WSE3.0設置 WSE3.0Settings button
(3)單獨的工具( Tools)
Wse Wsdl生成工具WseWsdl3.exe
Wse配置工具WseConfigEditor3.exe
X509認證管理工具X509Certificate3.exe
這些工具都可以在安裝目錄下找到如圖:
WSE 3.0只能和Visual Studio 2005集成安裝。Visual Studio 2008裡包含了WCF框架類庫,WCF 定位為新的 .NET Web 服務平台,該平台能夠完全替代現在對 WSE 所提供功能的需要。
安裝完成以後我們新建Web 服務項目。可以在項目右鍵屬性裡看到WSE 3.0設置,如圖:
就表示WSE 3.0安裝成功並且可以在項目裡使用。
【4】.代碼實現與分析
上面詳細講解了WSE的基本概念、基本加密算法和WSE3.0的安裝過程。下面我們來進行具體的代碼是實現部分, 之前的《WCF分布式應用程序開發必備知識系列》第4節Web服務已經涉及到Web服務安全的問題。當時的實現機制略有不同,使用的是SOAPHeader傳遞用戶令牌,在服務斷進行驗證。今天我們使用的是WSE3.類庫裡實現的類UserNameToken來進行用戶名字和密碼的傳輸。項目主要還是包括3個部分。一個Web Service項目、一個UserNameToken類庫和測試的客戶端
1)首先來看MyUsernameTokenManager的實現,它繼承自UsernameTokenManager,而UsernameTokenManager繼承SecurityTokenManager,SecurityTokenManager繼承自接口ISecurityTokenManager。UsernameTokenManager其中比較重要的方法是:
protected virtual string AuthenticateToken(UsernameToken token);
此方法提供了驗證互用令牌的具體實現
public static WindowsPrincipal LogonUser(string username, string password);
實現Window策略的驗證用戶名和密碼
protected virtual void VerifyHashedPassword(UsernameToken token, string authenticatedPassword);
驗證用戶的哈希密碼
protected virtual void VerifyPassword(UsernameToken token, string authenticatedPassword);
驗證密碼的正確性
protected virtual void VerifyPlainTextPassword(UsernameToken token, string authenticatedPassword);
驗證這個明文密碼的正確性
public override void VerifyToken(SecurityToken token);
最後以個是驗證用戶令牌的包含的用戶名和密碼的有效性。
其中最重要的是AuthenticateToken方法。WSE3.0框架會調用我們重寫的方法來驗證從SoapHeader裡提取生成的用戶令牌UsernameToken。
下面我們給處具體的代碼:
namespace MyUsernameTokenManager
{
//[SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.AllFlags)]
public class MyUsernameTokenManager : UsernameTokenManager
{
/**//// <summary>
//構造函數.
/**//// </summary>
public MyUsernameTokenManager()
{
}
/**//// <summary>
/// AuthenticateToken重寫實現。任何使用WSE框架安全機制的web服務必須遵守這個契約
protected override string AuthenticateToken(UsernameToken token)
{
// 返回客戶端UsernameToken傳遞的用戶密碼
//這裡相當於是一個解密的過程。WSE對於客戶端的SOAP頭信息,
//反序列化得到的信息生成UsernameToken的實例。
//這裡可以訪問數據庫獲得密碼,或者任意密碼驗證的復雜業務邏輯;
return "123456789";
}
}
}
在代碼中重載AuthenticateToken方法。服務端接收到含有UsernameToken實例的SOAP消息後,WSE將 UsernameToken反序列化,並調用VerifyToken方法,而VerifyToken方法在執行過程中又會調用 AuthenticateToken方法,這個方法會返回一個口令值,WSE會拿它與UsernameToken中的口令進行對比。
2)服務端實現很簡單,只包含一個方法,代碼如下:
using Microsoft.Web.Services3;
//using UsernameTokenManagerFrankXu;
[WebService(Namespace = "http://www.cnblogs.com/frank_xl/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
public Service () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string HelloWorld() {
return "Hello Guys, I 'm Frank Xu Lei";
}
}
3)客戶端代碼,主要是添加Web 引用。實例化Web服務的代理類,設置UserNameToken來調用web 服務的過程。
//客戶端通過服務代理和服務端交互
namespace WSEUserNametokenClient
{
class Program
{
static void Main(string[] args)
{
// 創建Web service proxy的實例
ServiceWse serviceProxy = new ServiceWse();
//通過UsernameToken類的實例添加用戶名與口令。
UsernameToken token = new UsernameToken("FrankXu", "123456789", PasswordOption.SendPlainText);
// 設置用戶令牌到服務代理
serviceProxy.SetClientCredential(token);
// 代理設置策略
//serviceProxy.SetPolicy("ClientPolicy");
//調用服務方法
string result = serviceProxy.HelloWorld();
try
{
Console.WriteLine(result);//打印結果
Console.WriteLine("Calling {0}", result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// Success!
Console.WriteLine("Web Service called successfully");
//For debug
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}
}
首先是創建Web service proxy的實例ServiceWse serviceProxy = new ServiceWse();
然後通過UsernameToken類的實例添加用戶名與口令。使用UsernameToken 設置用戶名和密碼 UsernameToken token = new UsernameToken("FrankXu", "123456789", PasswordOption.SendPlainText);
最後 設置用戶令牌到服務代理 serviceProxy.SetClientCredential(token)
運行結果顯示成功調用了服務,並且輸出正確的結果。
【5】.總結。
以上是本節的全部內容:WSE3.0框架介紹、安全基本概念、下載與安裝、代碼實現與分析。這裡值得注意的地方:(1)每個項目都要添加WSE3.0程序集Microsoft.Web.Services3的引用,不然項目會報錯。最後我還會照例放出文章的(2)例子代碼比較簡單。只是簡單應用了WSE3.0的基本機制。其實不難理解,WSE3.0的用戶密碼加密就是在客戶端設置用戶令牌的時候進行。而服務端的AuthenticateToken方法裡實現的其具體的密碼驗證過程,包括具體的驗證策略算法等扥,最終返回的就是客戶端成精傳遞的密碼。
希望通過本章的學習大家對WSE3.0 Web服務安全開發有個基本的了解,下一節我們來學習相對復雜的WSE3.0 策略配置來實現密碼加密與驗證。
本文配套源碼