原文:WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding
今天繼續介紹WCF分佈式安全開發實踐(11):消息安全模式之Certificate身份驗證:Message_Certificate_WSHttpBinding 。本文介紹的內容主要是:主要是消息安全模式的證書身份驗證方式,基於WSHttpBinding綁定協議的實現過程。主要內容:基本概念,然後是製作證書、服務端配置、客戶端配置、總結。這裏應該和Transport傳輸安全模式之證書身份驗證對應,但是消息安全模式這裏不使用https。安全基於TLS,傳輸層安全連接。
【0】消息安全模式之證書客戶端身份驗證:
消息安全模式之證書身份驗證需要服務器需要一個有效的可用於TLS 加密和向客戶端驗證服務身份的 X.509 證書,並且客戶端必須信任此服務器證書。而客戶端同樣要提供一個有效的證書,來證明自己的身份。 這裏使用http協議。建議安全上下文以後,使用共享安全上下文對SOAP消息進行加密和簽名。使用證書對客戶端和服務進行身份驗證。也就是客戶端提供有效證書纔可以訪問此服務。
1.身份驗證(服務器):提供證書,(使用 HTTP)用於初始會話協商和證明服務身份。
2.身份驗證(客戶端):客戶端證書進行身份驗證
WCF消息安全模式之證書身份驗證的架構如下:
客戶端建立TLS安全上下文以後,會使用商定的密碼對消息簽名,客戶端使用證書加密數據,服務端使用證書解密數據,保證數據的安全和機密性,消息簽名放置被篡改。
這裏客戶端提供的是有效的證書,服務器端進行驗證。
下面是製作證書的過程,和傳輸安全模式的過程一樣,這裏直接使用相同證書製作工具,新啓用端口8001。
【1】製作證書:
(1)使用makecert 工具:Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示行。
輸入:makecert -sr localmachine -ss My -n CN=WCFServerPK -sky exchange -pe -r
輸入:makecert -sr localmachine -ss My -n CN=WCFClientPK -sky exchange -pe -r。
-這裏製作了連個證書,主要只使用一個WCFServerPK,可以到出密鑰文件pfx,後續我們要導入到其他存儲區,設置爲信任的證書。WCFClientPK -是爲以後文章準備的,也是可以設置爲信任的證書。
(2) 打開瀏覽器---->Internet 選項----->內容----->證書----->個人,默認是保存到當前用戶CurrentUser,你會看到剛纔製作的證書。這個可以查看部分證書,但是功能有限。我們還是使用控制檯證書管理工具。
(3)使用MMC建立證書控制單元查看證書的信息:
開始--運行--MMC--控制檯--添加刪除單元--證書--當前用戶和計算機各添加一個。能查看和管理CurrentUser和LocalMachine的證書。如圖:
(4)導入證書到信任的人和信任的CA機構裏。步驟如下:
1.導出證書文件,帶密鑰的pfx文件。使用mmc,保存到桌面位置(方便查找)。這裏記住你製作證書的密碼。要使用。
2.導入證書到信任的人。使用任務-導入嚮導--選擇證書文件,導入即可。
3.導入證書到信任的機構,使用任務-導入嚮導--選擇證書文件,導入即可。這個證書就被信任了。
【3】服務端配置:
服務器證書配置完成以後,我們來配置服務端相關的文件,這裏簡單。也可以使用代碼來完成。
(1)服務類定義:
重複使用以前定義的服務類代碼。 這裏服務類就一個方法就是更具用戶的name來打印調用時間,代碼如下:
//1.服務契約
[ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
public interface IWCFService
{
//操作契約
[OperationContract]
string SayHello(string name);
}
//2.服務類,繼承接口。實現服務契約定義的操作
public class WCFService : IWCFService
{
//實現接口定義的方法
public string SayHello(string name)
{
Console.WriteLine("Hello! {0},Calling at {1} ", name,DateTime.Now.ToLongTimeString());
return "Hello! " + name;
}
}
(2)消息安全模式配置:
使用消息安全模式,採用客戶端證書身份驗證策略,Message安全模式下的證書驗證方式配置信息如下:
<wsHttpBinding>
<binding name="BindingConfigration">
<security mode="Message">
<transport clientCredentialType="None"/>
<message clientCredentialType="Certificate" negotiateServiceCredential="true" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
這裏允許啓用安全協商和建立安全上下文。這個配置要應用到服務的終結點配置上。纔會生效。
(3)證書使用:
服務器端證書主要是在建立TLS連接會話的時候,證明服務端的身份合法性。
在服務行爲節點屬性裏配置使用證書WCFServerPK,其它設置採用默認方式。這裏和WCF分佈式安全開發實踐(7):消息安全模式之匿名客戶端:Message_None_WSHttpBinding 配置一樣,具體代碼如下:
behaviors>
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="WCFServerPK" storeLocation="LocalMachine"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
這裏指定了服務端證書的查找位置和查找條件,我們證書存儲在LocalMachine 個人區域。使用標題進行查找。如果相同標題,需要制定唯一的查找條件。保證查找證書的唯一性。否則會出異常。
(4)這裏我們不需要使用Https傳輸協議,直接使用http協議即可,服務終結點的配置信息如下:
<services>
<service behaviorConfiguration="WCFService.WCFServiceBehavior" name="WCFService.WCFService" >
<endpoint
address="WCFService"
binding="wsHttpBinding"
bindingConfiguration="BindingConfigration"
contract="WCFService.IWCFService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/"/>
</baseAddresses>
</host>
</service>
</services>
我們的服務元數據終結點使用基地址:http://localhost:8001/。
【4】客戶端配置:
這個過程和之前的傳輸安全模式下,參考WCF分佈式安全開發實踐(5):傳輸安全模式之Certificate身份驗證:Transport_Certificate_WSHttpBinding , 添加服務的過程一樣。直接引用。
(1)引用元數據:
因爲服務的元數據交換節點啓用了Http協議,我們在客戶端項目添加元數據地址http://localhost:8001/mex查找服務信息的時候,界面如下:
繼續就會添加完畢服務引用。過程和普通的添加服務元數據引用一樣,會產生客戶端相關代碼文件。輸入命名空間,現在我們點擊Ok。等待完成即可。
(2)配置文件:
客戶端配置文件使用默認設置,主要是安全模式的設置要如下,與服務端匹配。使用證書驗證方式。
bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWCFService">
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
(3)客戶端證書:
這裏我們要在配置文件裏提供客戶端的證書,也可以採用代碼方式提供客戶端證書。配置文件的方式比較簡單。
直接在endpointBehaviors裏設置以後,應用到終結點行爲配置上就可以了。代碼如下:
<behaviors>
<endpointBehaviors>
<behavior name="endpointBehavior">
<clientCredentials>
<clientCertificate storeName="My"
x509FindType="FindBySubjectName"
findValue="WCFClientPK"
storeLocation="CurrentUser"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
(4)測試代碼:
等待代碼生成結束,我們這裏就直接生成客戶端代理類的實例來調用服務進行測試。這裏客戶端在調用服務以前,必須信任證書,這裏我們使用了一段通用的代碼,來建立TLS使用。這裏會信任服務器的證書。代碼如下:
public static class Util
{
/// <summary>
/// Sets the cert policy.
/// </summary>
public static void SetCertificatePolicy()
{
ServicePointManager.ServerCertificateValidationCallback
+= RemoteCertificateValidate;
}
/// <summary>
/// Remotes the certificate validate.
/// </summary>
private static bool RemoteCertificateValidate(
object sender, X509Certificate cert,
X509Chain chain, SslPolicyErrors error)
{
// trust any certificate!!!
System.Console.WriteLine("Warning, trust any certificate");
return true;
}
}
客戶端測試代碼很簡單,我們不需要提供客戶端證書了,因爲配置文件裏已經設置完畢。接下來就是通過客戶端代理來調用WCF服務。代碼如下:
static void Main(string[] args)
{
try
{
Console.ForegroundColor = ConsoleColor.Green;
WCFClient.ClientProxy.WCFServiceClient wcfServiceProxy = new WCFClient.ClientProxy.WCFServiceClient("WSHttpBinding_IWCFService");
//通過代理調用SayHello服務
string sName = "Frank Xu Lei Message Certificate WSHttpBinding";
string sResult = string.Empty;
Util.SetCertificatePolicy();
sResult = wcfServiceProxy.SayHello(sName);
Console.WriteLine("Returned Result is {0}", sResult);
}
catch (Exception e)
{
Console.WriteLine("Exception : {0}", e.Message);
}
//For Debug
Console.WriteLine("Press any key to exit");
Console.Read();
}
這裏也可以使用代碼來設置證書wcfServiceProxy.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("WCFClientPK.pfx", "password");WCFClientPK.pfx是導出的客戶端證書的文件,包含密鑰,密碼爲保護密碼。
(4)測試結果:
啓動宿主程序,然後啓動客戶端程序,客戶端成功調用服務,宿主打印的消息。如圖:
【5】總結
Windows Communication Foundation (WCF) 服務和客戶端。WCF安全機制都是依賴現有的安全體系和框架來完成的。這裏的消息安全模式下的客戶端證書身份驗證,其實沒有太大的變化。就是使用證書來驗證客戶端的有效性,合法性。
(1)服務器需要一個證明服務器身份和有效的可用於TLS傳輸層安全的 X.509 證書,並且客戶端必須信任此服務器證書。
(2)客戶端提交證書的方式與傳輸安全之證書驗證方式一樣,服務器端需要提供證書,但是不需要httpcfg.exe設置。
(3)初始協商需要服務器證書來建立TLS連接,協商完畢以後,建立共享安全上下文,這裏使用商定的加密算法對SOAP消息進行加密和簽名。
(4)如果你啓用協商,而不把服務器證書在客戶端設置信任,導入信任的辦法機構,會出現SOAP安全協商失敗的異常。
(5)這裏客戶端調用WCF服務以前要提供提供了有效的證書,和Transport安全模式的證書驗證方式類似。差別只是在於安全機制,前者使用的是HTTPS來保證通信安全,後者採用TLS。相同的地方都是在建立連接之前進行客戶端證書身份驗證。
(6)參考代碼:
Tag標籤: WCF分佈式安全開發實踐,Message,證書驗證,消息安全模式之Certificate身份驗證
/Files/frank_xl/8.1.WCFServiceSecurityDemoFrankXuLei_Message_Certificate_WSHttpBinding.rar