转载自[WCF安全系列]谈谈WCF的客户端认证[Windows认证]

结束了服务认证的介绍之后,我们接着介绍WCF双向认证的另一个方面,即服务对客户端的认证,简称客户端认证。客户端认证采用的方式决定于客户端凭证的类型,内容只要涉及基于以下三种典型客户凭证类型的认证:Windows、用户名和X.509证书。从编程的角度来讲,Windows认证是最为简单的认证方式。在这种认证方式下,客户端进程运行的Window帐号对应的Windows凭证被自动作为调用服务的客户端凭证,所以无需显示指定具体的Windiws凭证

如果需要另一个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对象的相似之处在于它也具有文本值。但是,SecureString对象的值是自动加密的,在应用程序将它标记为只读之前可以进行修改,并且可由应用程序或.NET Framework垃圾回收器将其从计算机内存中删除

当你进行服务调用的时候,不管你是直接采用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凭证的设置。

    using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorService"))
    {
       NetworkCredential credential = channelFactory.Credentials.Windows.ClientCredential;
        credential.Domain   = "DomainName";
        credential.UserName = "UserName";
        credential.Password = "Password";
     
        ICalculator calculator = channelFactory.CreateChannel();
        double result = calculator.Add(1, 2);
   }

 

posted on 2016-06-12 11:52  JustYong  阅读(276)  评论(0)    收藏  举报