閱讀953 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[WCF安全係列]談談WCF的客戶端認證[Windows認證]

結束了服務認證的介紹之後,我們接著介紹WCF雙向認證的另一個方麵,即服務對客戶端的認證,簡稱客戶端認證。客戶端認證采用的方式決定於客戶端憑證的類型,內容隻要涉及基於以下三種典型客戶憑證類型的認證:Windows、用戶名和X.509證書。從編程的角度來講,Windows認證是最為簡單的認證方式。在這種認證方式下,。

如果需要另一個Windows帳號的名義調用服務,客戶端就需要通知指定Windows帳號和密碼的方式顯式地進行客戶端Windows憑證的設置。Windows憑證在WCF通過類型WindowsClientCredential表示。下麵給出了WindowsClientCredential的定義,從中我們可以看到真正的憑證最終保存在類型為NetworkCredential的ClientCredential屬性中。通過該屬性,你可以指定Windows憑證的域名、用戶名和密碼。

   1: public sealed class WindowsClientCredential
   2: {
   3:     //其他成員
   4:     public bool AllowNtlm { get; set; }
   5:     public NetworkCredential ClientCredential { get; set; }
   6: }
   7: public class NetworkCredential : ICredentials, ICredentialsByHost
   8: {
   9:     //其他成員
  10:     public string Domain { get; set; }
  11:     public string UserName { get; set; }
  12:     public string Password { get; set; }
  13:     public SecureString SecurePassword { get; set; }
  14: }

從上麵給出的代碼我們可以看到,NetworkCredential除了一個以String類型表示的Password屬性之外,還有另一外一個相關的SecurePassword屬性,其類型為SecureString。我們知道String類型具有恒定性(Immutability),一旦被創建,它將在整個進程生命周期內一直存在。因此,如果某個String對象含有諸如密碼、信用卡號碼或個人數據等敏感信息,則因為應用程序無法從計算機內存中刪除這些數據,便存在信息在使用後可能被泄漏的危險。SecureString對象與String對象的相似之處在於它也具有文本值。但是,。

當你進行服務調用的時候,不管你是直接采用ChannelFactory<TChannel>創建服務代理的方式,還是通過導入元數據生成客戶端代理的方式,設置Windows憑證都很容易。ChannelFactory<TChannel>的基類ChannelFactory和ClientBase<TChannel>中都定義了一個隻讀屬性ClientCredentials,該屬性的類型為ClientCredentials。對於類型ClientCredentials,我們應該不會感到陌生,因為在前麵的實例演示中我們通過它實現了對服務證書認證模式的改變。我們表示Windows憑證的WindowsClientCredential對象作為隻讀屬性Windows定義在ClientCredentials中,相關類型的定義如下所示。

   1: public class ChannelFactory<TChannel> : ChannelFactory
   2: { 
   3:     //省略成員
   4: }
   5: public abstract class ChannelFactory 
   6: {
   7:     //其他成員
   8:     public ClientCredentials Credentials { get; }   
   9: }
  10: public abstract class ClientBase<TChannel> 
  11: {
  12:     //其他成員
  13:     public ClientCredentials ClientCredentials { get; }
  14: }
  15: public class ClientCredentials : SecurityCredentialsManager, IEndpointBehavior
  16: {
  17:    //其他成員
  18:     public WindowsClientCredential Windows { get; }
  19: }

下麵給出的代碼片斷為你演示了當你采用通過ChannelFactory<TChannel>創建的服務代理進行服務調用時如何進行Windows憑證的設置。

   1: using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorService"))
   2: {
   3:     NetworkCredential credential = channelFactory.Credentials.Windows.ClientCredential;
   4:     credential.Domain   = "DomainName";
   5:     credential.UserName = "UserName";
   6:     credential.Password = "Password";
   7:  
   8:     ICalculator calculator = channelFactory.CreateChannel();
   9:     double result = calculator.Add(1, 2);
  10:     ...
  11: }

關於WCF下的Windows認證,還有一點值得一提。上麵我們給出了WindowsClientCredential的定義,不知道你是否注意到了它具有一個布爾類型的屬性。這個屬性實際上涉及到關於Windows認證協議的問題。WCF集成的Windows認證是基於SSPI(Security Support Provider Interface),這是一套標準的安全編程接口,而具體安全功能的實現定義在相應的SSP(Security Support Provider)。SSPI是麵向接口的安全編程成為可能,這樣的好處顯而易見:在基於不同SSP的安全環境中,你的程序都能兼容。

Windows提供了三種典型的SSP:、和。前兩種分別基於我們熟悉的Kerberos和NTLM,但是SPNEGO才是默認的選項。SPNEGO的全名為“Simple and Protected GSSAPI Negotiation Mechanism”,而GSSAPI(Generic Security Services Application Program Interface)是互聯網工程任務組(IETF)指定的保準的安全應用編程接口。SPNEGO,故名思義,就是通過協商(Negotiation)確定一種適合的GSS API。SPNEGO在Windows下的協商機製是這樣的:首選Kerberos,如果不可用則退而求其次,選用NTLM。

不論從安全性還是互操作性(實際上Kerberos本身就是一種標準),Kerberos都要優於NTLM,但是Keberos僅限於基於AD的域環境中使用。。


作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
原文鏈接

最後更新:2017-10-26 16:34:36

  上一篇:go  [WCF安全係列]服務憑證(Service Credential)與服務身份(Service Identity)
  下一篇:go  [WCF安全係列]談談WCF的客戶端認證[用戶名/密碼認證]