WCF传输安全3:基于SSL的WCF对客户端验证

上文我们演示了,客户端对服务器端身份的验证,这一篇来简单演示一下对客户端身份的验证。比如我们发布的服务,只想让若干客户端调用和访问。这种情况应该怎么做呢,这就是今天要演示的客户端认证。

对客户端的认证基本分为三种:

1、  windows 身份验证

2、  用户名密码方式验证

3、  证书认证

我们今天主要用第二种方式来对客户端进行验证。

WCF的传输安全中,HttpClientCredentialType 提供了6种客户端凭证来体现服务端对客户端的认证方式,(以下对6种认证方式的解释,摘自蒋金楠《WCF技术剖析》):

None: 客户端无须指定用户凭证,即匿名认证。

Basic:采用Basic认证方式对客户端进行认证,这种方式客户端需要提供有效的用户名和密码,但仅采用较弱的方式对密码进行加密。当且仅当确定客户端和服务器端直接的连接绝对安全的情况下采用此方式。

Digest:Digest认证提供与Basic类似的认证功能,但是安全性有所提升,主要体现在并不是将用户名和密码直接进行网络传输,而是对其进行MD5 运算得到一个哈希码,最终传输的是该哈希码。

Ntlm:表示基于NTLM方式的windows集成认证。

Windows:表示使用windows集成认证,如果能够使用Kerberos,则直接采用Kerberos进行认证,否则才使用NTLM

Certificate:表示客户端的身份通过一个X.509数字证书表示,服务端通过校验证书的方式来确定客户端的真实身份

Windows 身份的验证 基本上计算机都需要加入域的,需要域控制器来处理客户端的身份。有点复杂,我们就实验一简单的用户名密码方式来对客户端进行验证。说白了,就是服务器端提供证书,客户端通过该证书对服务器端进行身份的验证,服务器端根据客户端提供的用户名密码来判断是否能允许调用服务。

我们还用我们上一篇的例子就可以,将代码稍微改动一下,就可以实现。

首先,我们 将 Host_Server 中App.config 文件中 bindings 节点中

<transport clientCredentialType="None"/>

修改为:

<transport clientCredentialType="Basic"/>

这时候我们重新生成一下Host_Server,并使其运行后,更新一下Client1 的服务引用,再运行Client1,我们会发现服务调用失败,我们抛出这个错误提示,如下图:

由于我们修改basic方式对客户端进行认证,这时候我们的客户端就需要提供一个用户名和密码来访问这个服务,这个访问服务的密码是通过生成的客户端代理类 中的一个属性 ClientCredentials.UserName.UserName 和 ClientCredentials.UserName.Password 来提供的。但是我们在WCF服务中什么地方来验证客户端提供的用户名和密码呢?比如能够提供用户名 admin 和密码 123456 的客户端,我们都认为是合法的客户端,都允许和服务进行通信。我们在WCF服务端可以这样进行判断:

首先,在我们的服务类库LxServices中添加引用:System.IdentityModel 和 System.IdentityModel.Selectors,并增加一个自定义身份验证类 CustomIdentityVerification 使其继承 UserNamePasswordValidator类,并重写其中的 Validate 方法,代码如下:

复制代码
using System;
using System.IdentityModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

namespace LxServices
{
    public class CustomIdentityVerification : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            //这里可以对通过输入的用户名密码进行验证,比如可以在数据库中进行查询
            if (userName != "admin" || password != "123456")
            {
                throw new SecurityTokenException("用户名密码错误!");
            }
        }
    }
}
复制代码

然后,我们需要修改WCF宿主程序的配置文件App.config,使我们的这个自定义的验证类生效,因此在服务行为serviceBehaviors节点中增加:

复制代码
<!--服务器端提供证书-->
<serviceCredentials>
     <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="Lx-PC" storeLocation="LocalMachine"/>
      <clientCertificate >
           <authentication certificateValidationMode="None"/>
       </clientCertificate>
       <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="LxServices.CustomIdentityVerification,LxServices" />
</serviceCredentials>
复制代码

以下是宿主程序完整的App.config文件代码:

宿主程序 App.config 代码

启动服务器端宿主程序后,更新Client1 的服务引用,并修改调用代码如下:

Client1 Main 函数代码

我们的代码修改完成,我们运行一下客户端Client1,并输入用户名 admin 和密码 123456,可以成功调用服务:

我们输入一次错误的用户名和密码,比如输入 123,就不会成功调用服务,结果如下图所示:

至此,我们利用用户名密码方式对客户端进行验证的这个Demo ,就结束了,下一篇我们来演示一下传输安全中对客户端也使用证书方式的认证。

本例源码下载

作者:Rising Sun
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
分类: WCF

WCF

 
摘要: 上文我们演示了,客户端对服务器端身份的验证,这一篇来简单演示一下对客户端身份的验证。比如我们发布的服务,只想让若干客户端调用和访问。这种情况应该怎么做呢,这就是今天要演示的客户端认证。对客户端的认证基本分为三种:1、 windows 身份验证2、 用户名密码方式验证3、 证书认证我们今天主要用第二种方式来对客户端进行验证。WCF的传输安全中,HttpClientCredentialType 提供了6种客户端凭证来体现服务端对客户端的认证方式,(以下对6种认证方式的解释,摘自蒋金楠《WCF技术剖析》):None: 客户端无须指定用户凭证,即匿名认证。Basic:采用Basic认证方式对客户端进行阅读全文
posted @ 2012-09-18 15:38 Rising_Sun 阅读(364) | 评论 (1) 编辑
 
摘要: 这一篇我们利用上一篇制作的证书,来演示一个基于SSL的WCF服务,客户端需要验证服务器端的身份,服务器端不对客户端进行任何验证,即匿名客户端。一、项目结构为了演示方便,把项目分成了6层,首先说明一下项目的结构:程序集名称引用简单说明Client1控制台客户端1,调用采用控制台自宿主的WCFClient2控制台客户端2,调用采用IIS宿主的WCFHost_ServerSystem.ServiceModelLxContracts(项目中)LxServices (项目中)控制台服务端采用控制台宿主WCFHostWeb_ServerSystem.ServiceModelLxContracts(项目中)阅读全文
posted @ 2012-09-13 16:02 Rising_Sun 阅读(790) | 评论 (1) 编辑
 
摘要: 近几日一直在学习WCF传输安全方面的知识,在园子里淘了好久,也查了不少资料,终于有所了解,遂成此文,与大家分享!一、WCF中的安全方式说到安全就会涉及到认证,消息一致性和机密性,WCF的安全方式分为两种,即传输安全和消息安全。传输安全和消息安全的区别:传输安全提供点对点的安全: 比如 A 提供服务,B和C直接连接到A,这时候A与B 及 A与C直接的传输是安全的,如果B通过C连接到A,那么A与B直接是安全的,B与C之间是不安全的。消息安全:是把安全机制都应用在消息级别上面的,能够提供端对端的安全,不管消息的路由路径多么复杂,也能保证消息的安全传输。传输安全我们一般应用在局域网中,消息安全主要应用阅读全文
posted @ 2012-09-12 20:53 Rising_Sun 阅读(887) | 评论 (5) 编辑
原文地址:https://www.cnblogs.com/Leo_wl/p/2691480.html