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 ...
随机推荐
- yum仓库客户端搭建和NTP时间同步客户端配置
一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...
- Git 项目提交代码及一些常用命令
在dev_ysg分支 : git add . //把项目添加到仓库 git commit -m "test" // 提交加注释 git push //推到dev_ysg分支上去 g ...
- Leecode刷题之旅-C语言/python-136只出现一次的数字
/* * @lc app=leetcode.cn id=136 lang=c * * [136] 只出现一次的数字 * * https://leetcode-cn.com/problems/singl ...
- labview在编写程序框图中遇到的一些布尔按钮控制布尔指示灯问题
上图布尔控件按下,数据0x04成功发送给下位机,布尔灯不亮. ............... ............. ........... 下图布尔控件按下, ...
- 6-C++远征之封装篇[上]-学习笔记
C++远征之封装篇(上) 课程简介 类(抽象概念),对象(真实具体) 配角: 数据成员和成员函数(构成了精彩而完整的类) 构造函数 & 析构函数(描述了对象的生生死死) 对象复制和对象赋值 ( ...
- 复位自动ID的问题有兩種方法
复位自动ID的问题 有兩種方法: 方法1: truncate table 你的表名 --這樣不但將數據刪除,而且可以重新置位identity屬性的字段. ...
- Kubernetes-创建集群(四)
Kubernetes可以运行在多种平台,从笔记本到云服务商的虚拟机,再到机架上的裸机服务器.要创建一个Kubernetes集群,根据不同的场景需要做的也不尽相同,可能是运行一条命令,也可能是配置自己定 ...
- python2.7入门---字典(Dictionary)
这次咱们记录的是python中的字典这个鬼,首先我们得了解,字典是另一种可变容器模型,且可存储任意类型对象.字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 ...
- java 堆栈内存分析详解
计算机术语里面堆和栈代表不同的存储结构:stack-栈:heap-堆 所以java虚拟机(JVM)中堆和栈是两种内存 堆.栈对比 对比点 堆 栈 JVM中的功能 内存数据区 内存指令区 动静态 运行时 ...
- LeetCode:17. Letter Combinations of a Phone Number(Medium)
1. 原题链接 https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/ 2. 题目要求 给定一 ...