WCF身份验证一:消息安全模式之<Certificate>身份验证
【0】消息安全模式之证书客户端身份验证:
消息安全模式之证书身份验证需要服务器需要一个有效的可用于TLS 加密和向客户端验证服务身份的 X.509 证书,并且客户端必须信任此服务器证书。而客户端同样要提供一个有效的证书,来证明自己的身份。 这里使用http协议。建议安全上下文以后,使用共享安全上下文对SOAP消息进行加密和签名。使用证书对客户端和服务进行身份验证。也就是客户端提供有效证书才可以访问此服务。
2.身份验证(客户端):客户端证书进行身份验证

这里客户端提供的是有效的证书,服务器端进行验证。
下面是制作证书的过程,和传输安全模式的过程一样,这里直接使用相同证书制作工具,新启用端口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,你会看到刚才制作的证书。这个可以查看部分证书,但是功能有限。我们还是使用控制台证书管理工具。
开始--运行--MMC--控制台--添加删除单元--证书--当前用户和计算机各添加一个。能查看和管理CurrentUser和LocalMachine的证书。如图:

1.导出证书文件,带密钥的pfx文件。使用mmc,保存到桌面位置(方便查找)。这里记住你制作证书的密码。要使用。
2.导入证书到信任的人。使用任务-导入向导--选择证书文件,导入即可。
3.导入证书到信任的机构,使用任务-导入向导--选择证书文件,导入即可。这个证书就被信任了。
【3】服务端配置:
服务器证书配置完成以后,我们来配置服务端相关的文件,这里简单。也可以使用代码来完成。
(1)服务类定义:
重复使用以前定义的服务类代码。 这里服务类就一个方法就是更具用户的name来打印调用时间,代码如下:
[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;
}
}
使用消息安全模式,采用客户端证书身份验证策略,Message安全模式下的证书验证方式配置信息如下:
<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 配置一样,具体代码如下:
<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>
(4)这里我们不需要使用Https传输协议,直接使用http协议即可,服务终结点的配置信息如下:
<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>
这个过程和之前的传输安全模式下,参考WCF分布式安全开发实践(5):传输安全模式之Certificate身份验证:Transport_Certificate_WSHttpBinding , 添加服务的过程一样。直接引用。
(1)引用元数据:
因为服务的元数据交换节点启用了Http协议,我们在客户端项目添加元数据地址http://localhost:8001/mex查找服务信息的时候,界面如下:

(2)配置文件:
客户端配置文件使用默认设置,主要是安全模式的设置要如下,与服务端匹配。使用证书验证方式。
<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>
这里我们要在配置文件里提供客户端的证书,也可以采用代码方式提供客户端证书。配置文件的方式比较简单。
直接在endpointBehaviors里设置以后,应用到终结点行为配置上就可以了。代码如下:
<endpointBehaviors>
<behavior name="endpointBehavior">
<clientCredentials>
<clientCertificate storeName="My"
x509FindType="FindBySubjectName"
findValue="WCFClientPK"
storeLocation="CurrentUser"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
等待代码生成结束,我们这里就直接生成客户端代理类的实例来调用服务进行测试。这里客户端在调用服务以前,必须信任证书,这里我们使用了一段通用的代码,来建立TLS使用。这里会信任服务器的证书。代码如下:
{
/// <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;
}
}
{
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是导出的客户端证书的文件,包含密钥,密码为保护密码。
启动宿主程序,然后启动客户端程序,客户端成功调用服务,宿主打印的消息。如图:

Windows Communication Foundation (WCF) 服务和客户端。WCF安全机制都是依赖现有的安全体系和框架来完成的。这里的消息安全模式下的客户端证书身份验证,其实没有太大的变化。就是使用证书来验证客户端的有效性,合法性。
(1)服务器需要一个证明服务器身份和有效的可用于TLS传输层安全的 X.509 证书,并且客户端必须信任此服务器证书。
(2)客户端提交证书的方式与传输安全之证书验证方式一样,服务器端需要提供证书,但是不需要httpcfg.exe设置。
(3)初始协商需要服务器证书来建立TLS连接,协商完毕以后,建立共享安全上下文,这里使用商定的加密算法对SOAP消息进行加密和签名。
(4)如果你启用协商,而不把服务器证书在客户端设置信任,导入信任的办法机构,会出现SOAP安全协商失败的异常。
(5)这里客户端调用WCF服务以前要提供提供了有效的证书,和Transport安全模式的证书验证方式类似。差别只是在于安全机制,前者使用的是HTTPS来保证通信安全,后者采用TLS。相同的地方都是在建立连接之前进行客户端证书身份验证。
(6)参考代码:
以上基本是消息安全之证书验证方式的实现过程。相比WCF分布式安全开发实践(5):传输安全模式之Certificate身份验证:Transport_Certificate_WSHttpBinding 。它具有了消息安全的很多优点。提供了更加灵活的安全加密策略,使得我们客户端和服务器之间可以经过多个中间件,依然能够保证消息的机密性和完整性。也就是端到端(End-to-End)的安全机制。
这里大家试验的实验的时候,一定要设置服务端信任客户端证书。不然会出错误。
参考文章:
1.WCF分布式安全开发实践(5):传输安全模式之Certificate身份验证:Transport_Certificate_WSHttpBinding
2.WCF分布式安全开发实践(8):消息安全模式之用户名身份验证:Message_UserName_WSHttpBinding3.http://social.microsoft.com/Forums/zh-CN/wcfzhchs/thread/e1aa7bea-90d8-41e6-b91b-7addba44f8e3
4.WSE3.0构建Web服务安全(2):非对称加密、公钥、密钥、证书、签名的区别和联系以及X.509 证书的获得和管理,具体5.http://msdn.microsoft.com/en-us/library/ms733098.aspx
WCF身份验证一:消息安全模式之<Certificate>身份验证的更多相关文章
- WCF身份验证二:基于消息安全模式的自定义身份验证
使用X509证书进行身份验证应该说是WCF安全模型中最”正常”的做法, 因为WCF强制要求使用证书加密身份数据, 离开了证书, 所有的身份验证机制拒绝工作, WCF支持的身份验证机制也相当复杂, 这里 ...
- WCF 学习总结5 -- 消息拦截实现用户名验证(转)
WCF建立在基于消息的通信这一概念基础上.通过方法调用(Method Call)形式体现的服务访问需要转化成具体的消息,并通过相应的编码(Encoding)才能通过传输通道发送到服务端:服务操作执行的 ...
- (WCF初体验)WCF的认证和消息保护
最近做WCF开发,有个需求是在服务端做认证,网上查资料了解到可以用UserName和Password 来做认证,只需要写好配置文件和在服务端写好验证类就行了,但是网上普遍的博文都是需要用证书,而我自己 ...
- 两步验证杀手锏:Java 接入 Google 身份验证器实战
两步验证 大家应该对两步验证都熟悉吧?如苹果有自带的两步验证策略,防止用户账号密码被盗而锁定手机进行敲诈,这种例子屡见不鲜,所以苹果都建议大家开启两步验证的. Google 的身份验证器一般也是用于登 ...
- WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ
之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ ...
- [老老实实学WCF] 第十篇 消息通信模式(下) 双工
老老实实学WCF 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOneWay属性来改变模式.在这一篇中我们来研究双 ...
- Yii 验证和消息
setFlash(), getFlash()可以完成验证成功后提示 <?php # 成功信息提示 Yii::app()->user->setFlash('success', &quo ...
- laravel的Validation检索验证错误消息
基本用法 处理错误消息 错误消息和视图 可用的验证规则 有条件地添加规则 自定义错误消息 自定义验证规则 基本用法 Laravel提供了一个简单.方便的工具,用于验证数据并通过validation类检 ...
- 腾讯消息队列CMQ部署与验证
环境 IP 备注 192.168.1.66 node1 前置机 192.168.1.110 node2 192.168.1.202 node3 架构图 组件介绍 组件 监听端口 access 1200 ...
随机推荐
- Qt基于tcp协议网络编程
基于Qt网络编程: 基于tcp协议 c/s模式编程 所需要的类:QTcpServer QTcpSocket 利用qt基于tcp协议编写c/s模式程序: 两个类中的信号: QTcpServer : ne ...
- spring mvc中几种获取request对象的方式
在使用spring进行web开发的时候,优势会用到request对象,用来获取访问ip.请求头信息等 这里收集几种获取request对象的方式 方法一:在controller里面的加参数 public ...
- 如何在linux系统内用openssl 生成 过期的证书
需求:验证过期的证书在系统中不能使用. 问题:如何生成过期的证书呢? 解决方法:1.调整系统时间 2.生成证书 3.验证证书startdate 和 enddate 是否符合你的预期 1.调整系统时间 ...
- 什么是token及怎样生成token
什么是token Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即 ...
- Python 一些好玩的函数
一.匿名函数 什么匿名是函数: 不需要使用def函数名的函数或者子程序 函数语法: lambda 参数:表达式 函数特点: 1.lambda只是一个表达式,省去定义函数过程,让代码更精简 2.lamb ...
- zookeeper相关知识与集群搭建
Zookeeper Zookeeper相关概念 Zookeeper概述 Zookeeper是一个分布式协调服务的开源框架,主要用来解决分布式集群中应用系统的一致性问题. Zookeeper本质上是一个 ...
- 电子商城实录------定义init初始化的方法
路由方法的设置 //路由方法 private static function dispatch(){ //获取控制器名称(类比:英文单词的后缀) $controller_name=CONTROLLER ...
- Spark-源码-Spark-StartAll Master Worler启动流程
Spark start-all>> """Master启动流程""" Master类 class Master( host: S ...
- 9.1 IIC驱动源码分析
学习目标:分析linux内核源码下的i2c总线驱动 drivers/i2c/busses/i2c-s3c2410.c 和 driver/i2c/chips/eeprom.c 设备驱动: 一.i2c驱动 ...
- 二维数组快速排序(sort+qsort)
二维数组快速排序 qsort是c中快速排序,如果简单的一维数组排序,想必大家的懂.现在看一下二维数组的排序,虽然可以冒泡但是太费时间了,我们这里使用qsort来快速排序,看代码应该看得懂吧. 代码: ...