轉帖|其它|編輯:郝浩|2011-05-26 15:16:11.000|閱讀 663 次
概述:整個安全傳輸是在WCF的信道層進行的,而綁定是信道層的締造者,所以終結點采用哪種類型的綁定以及對綁定的屬性進行怎樣的設置決定了信道層最終采用何種機制實現消息的安全傳輸。具體來說,我們可以通過綁定設置最終采用的安全模式,以及基于相應安全模式下進行認證和消息保護的行為。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
整個安全傳輸是在WCF的信道層進行的,而綁定是信道層的締造者,所以終結點采用哪種類型的綁定以及對綁定的屬性進行怎樣的設置決定了信道層最終采用何種機制實現消息的安全傳輸。具體來說,我們可以通過綁定設置最終采用的安全模式,以及基于相應安全模式下進行認證和消息保護的行為。
一、Binding安全相關的應用編程接口
不同的綁定類型由于其采用的傳輸協議不同,應用的場景也各有側重,很難提供一種統一的應用編程接口完成基于不同綁定的安全設置,所以每一種綁定都具有各自用于安全設置相關的類型。但是基于對安全的設置,大部分系統預定義綁定(不是所有)都具有類似于如下代碼片斷所示的屬性定義。
1: Public class XxxBinding
2: {
3: Public XxxSecurity Security {}
4: }
5: Public class XxxSecurity
6: {
7: Public XxxSecurityMode Mode{get;set;}
8: Public XxxTransportSecurity Transport{get;set;}
9: Public XxxMessageSecurity Message{get;set;}
10: }
對于某個綁定XxxBinding(Xxx泛指某種綁定類型,所有帶Xxx前綴的類型并不意味著它們代表完全一樣的字符),它具有一個專屬的XxxSecurity類型的Security屬性。而這個XxxSecurity類型一般具有三個屬性:Mode表示采用的安全模式,而Transport和Message用于針對Transport和Message安全模式下的設置。
對于圍繞著綁定進行的安全設置,我們首要的任務就是制定采用的安全模式。在安全模式確定之后,客戶端憑證的選擇決定了認證方最終采用怎樣的認證機制。接下來,我們就來談談針對不各種常用的系統預定義綁定,安全模式和基于安全模式的客戶端憑證如何設置。先從BasicHttpBinding談起。
二、BasicHttpBinding支持的安全模式
下面的代碼片斷表示BasicHttpBinding安全相關應用編程接口的定義,這和上面給出的“泛型綁定”的定義完全一致。通過Security屬性返回用于進行針對BasicHttpBinding安全設置的類型為BasicHttpSecurity。BasicHttpSecurity的Mode、Transport和Message三種屬性的類型分別為BasicHttpSecurityMode、HttpTransportSecurity和BasicHttpMessageSecurity。
1: public class BasicHttpBinding : Binding, IBindingRuntimePreferences
2: {
3: //其他成員
4: public BasicHttpSecurity Security { get; set; }
5: }
6: public sealed class BasicHttpSecurity
7: {
8: //其他成員
9: public BasicHttpSecurityMode Mode { get; set; }
10: public HttpTransportSecurity Transport { get; set; }
11: public BasicHttpMessageSecurity Message { get; set; }
12: }
枚舉BasicHttpSecurityMode中定義了BasicHttpBinding支持的5中安全模式。其中None為默認選項,表示并不采用任何安全機制,Transport、Message和TransportWithMessageCredential分別表示之前介紹的Transport、Message和Mixed安全模式。TransportWithMessageCredential表示“使用基于Message模式憑證的Transport模式”。由于Mixed安全模式通過Message模式實現對客戶端的認證,所以要求客戶端采用基于Message模式的憑證。而除客戶端認證的其他安全要素的實現則都是采用Transport模式。所以TransportWithMessageCredential在BasicHttpSecurityMode枚舉中的表示和我們講的Mixed模式從語義上講是一致的。TransportCredentialOnly是BasicHttpBinding所獨有的安全模式。它只提供針對于HTTP的客戶端認證,并不能提供消息一致性和機密性的保證。
1: public enum BasicHttpSecurityMode
2: {
3: None,
4: Transport,
5: Message,
6: TransportWithMessageCredential,
7: TransportCredentialOnly
8: }
三、基于Transport模式的客戶端憑證
HttpTransportSecurity用于進行針對Transport模式下的安全設置。而通過ClientCredentialType屬性,我們可以設置客戶端憑證的類型。該屬性類型為HttpClientCredentialType枚舉,定義其中的六個枚舉值表示支持的六種基于Tranport模式的客戶端憑證類型。HttpTransportSecurity和HttpClientCredentialType相關定義如下。
1: public sealed class HttpTransportSecurity
2: {
3: //其他成員
4: public HttpClientCredentialType ClientCredentialType {get; set; }
5: }
6: public enum HttpClientCredentialType
7: {
8: None,
9: Basic,
10: Digest,
11: Ntlm,
12: Windows,
13: Certificate
14: }
定義在枚舉類型HttpClientCredentialType中的六種不同的客戶端用戶憑證類型體現了服務端針對客戶端不同的認證方式:
無論是在進行服務寄宿的時候為ServiceHost添加終結點,還是在客戶端創建調用服務的終結點,都可以通過編程的方式來設置綁定的安全模式和客戶端用于憑證類型。如下面的代碼片斷所示,我們為BasicHttpBinding設置了Transport安全模式,并將其客戶端憑證設置成Windows。由于所有基于HTTP的綁定都通過HTTPS來實現Transport安全,所以當選擇Transport和TransportWithMessageCredential安全模式的情況下,終結點地址必須是一個HTTPS地址。
1: using(ServiceHost host = new ServiceHost(typeof(CalculatorService)))
2: {
3: var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
4: binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Windows;
5: host.AddServiceEndpoint(typeof(ICalculator), binding,
"//localhost/calculatorservice");
6: host.Open();
7: ...
8: }
服務調用代碼:
1: var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
2: binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.Windows;
3: using (ChannelFactory<ICalculator> channelFactory =
new ChannelFactory<ICalculator>
(binding, "//localhost/calculatorservice"))
4: {
5: ICalculator calculator = channelFactory.CreateChannel();
6: double result = calculator.Add(1, 2);
7: ...
8: }
對于包括客戶端憑證類型在內的針對綁定的安全設置,我們還是推薦采用配置的方式。基于綁定的配置節中具有一個<security>的字節點,用于進行安全相關的設置。采用的安全模式通過該節點的mode屬性設置。而給予Transport模式相關的設置則配置在<security>/<transport>配置節中,其中配置屬性clientCredentialType表示客戶端憑證類型。在下面的給出的配置片斷中,我為寄宿的服務添加了一個采用BasicHttpBinding的終結點,該綁定的模式被設置為Transport,并采用Certificate客戶端憑證類型。
1: <system.serviceModel>
2: <bindings>
3: <basicHttpBinding>
4: <binding name="transportBinding">
5: <security mode="Transport">
6: <transport clientCredentialType="Certificate"/>
7: </security>
8: </binding>
9: </basicHttpBinding>
10: </bindings>
11: <services>
12: <service name="Artech.WcfServices.Services.CalculatorService">
13: <endpoint address="//Jinnan-PC/calculatorservice"
binding="basicHttpBinding" bindingConfiguration="transportBinding"
contract="Artech.WcfServices.Contracts.ICalculator" />
14: </service>
15: </services>
16: </system.serviceModel>
四、基于Message模式的客戶端憑證
類型BasicHttpSecurity用于進行針對于BasicHttpBinding關于Message安全模式的相關設置。你同樣可以通過它的ClientCredentialType屬性設置客戶端憑證類型,該屬性類型為System.ServiceModel.BasicHttpMessageCredentialType枚舉。定義在BasicHttpMessageCredentialType中的兩個枚舉值(UserName和Certificate)表示支持的兩種客戶端憑證類型,它們分別代表基于用戶名/密碼的憑證和針對X.509證書的憑證。在默認的情況下采用用戶名/密碼的憑證。BasicHttpMessageSecurity和BasicHttpMessageCredentialType相關定義如下面的代碼片斷所示。
1: public sealed class BasicHttpMessageSecurity
2: {
3: public BasicHttpMessageCredentialType
ClientCredentialType { get; set; }
4: }
5: public enum BasicHttpMessageCredentialType
6: {
7: UserName,
8: Certificate
9: }
關于上述的兩種客戶端憑證,BasicHttpMessageCredentialType.UserName只能用在Mixed模式下。當你選擇了Message模式,則只能選擇BasicHttpMessageCredentialType. Certificate。 WCF為什么會具有如此一個限制,你會在后續文章中找到答案。舉個例子,我通過如下一段代碼對服務CalculatorService進行寄宿,并采用了一個采用Message模式的BasicHttpBinding。
1: using (ServiceHost host =
new ServiceHost(typeof(CalculatorService)))
2: {
3: var binding = new BasicHttpBinding
(BasicHttpSecurityMode.Message);
4: host.AddServiceEndpoint(typeof(ICalculator),
binding, "//localhost/calculatorservice");
5: host.Open();
6: ...
7: }
當ServiceHost被開啟的時候,如下圖所示的InvalidOperationException異常被拋出來,并提示“BasicHttpBinding綁定要求 BasicHttpBinding.Security.Message.ClientCredentialType 等效于安全消息的 BasicHttpMessageCredentialType.Certificate 憑據類型。為 UserName 憑據選擇Transport 或 TransportWithMessageCredential 安全性”。實際上這個異常消息不太正確,因為Tranport模式下根本就不存在UserName憑證類型。
在基于綁定的配置節中,Message模式相關選項通過<security>/<message>配置節進行設置。在該配置節中,clientCredentialType屬性用于設置客戶端憑證類型。在下面的配置片斷中,我為寄宿的服務添加了兩個采用BasicHttpBinding的終結點。其中第一個終結點的綁定為Message模式,并采用Certificate憑證。另一個終結點綁定為TransportWithMessageCredential模式,采用UserName憑證。為了保證服務寄宿的成功,我們還必須通過服務行為的形式為服務指定一個X.509證書作為服務憑證。這實際上涉及到了服務認證的話題,我們將本節后續部分進行介紹。
1: <system.serviceModel>
2: <behaviors>
3: <serviceBehaviors>
4: <behavior name="serviceCertificateBehavior">
5: <serviceCredentials>
6: <serviceCertificate findValue="Jinnan-PC"
x509FindType="FindBySubjectName" />
7: </serviceCredentials>
8: </behavior>
9: </serviceBehaviors>
10: </behaviors>
11: <bindings>
12: <basicHttpBinding>
13: <binding name="messageBinding">
14: <security mode="Message">
15: <message clientCredentialType="Certificate"/>
16: </security>
17: </binding>
18: <binding name="transportWithMessageCredentialBinding">
19: <security mode="TransportWithMessageCredential">
20: <message clientCredentialType="UserName" />
21: </security>
22: </binding>
23: </basicHttpBinding>
24: </bindings>
25: <services>
26: <service behaviorConfiguration="serviceCertificateBehavior"
name="Artech.WcfServices.Services.CalculatorService">
27: <endpoint address="//Jinnan-PC/calculatorservice1"
binding="basicHttpBinding"
28: bindingConfiguration="messageBinding"
contract="Artech.WcfServices.Contracts.ICalculator" />
29: <endpoint address="//Jinnan-PC/calculatorservice2"
binding="basicHttpBinding"
30: bindingConfiguration="transportWithMessageCredentialBinding"
contract="Artech.WcfServices.Contracts.ICalculator" />
31: </service>
32: </services>
33: </system.serviceModel>
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園