消息安全模式的证书身份验证方式,基于WSHttpBinding绑定协议的实现过程。主要内容:基本概念,然后是制作证书、服务端配置、客户端配置、总结。这里应该和Transport传输安全模式之证书身份验证对应,但是消息安全模式这里不使用https。安全基于TLS,传输层安全连接。  
【0】消息安全模式之证书客户端身份验证:
       消息安全模式之证书身份验证需要服务器需要一个有效的可用于TLS 加密和向客户端验证服务身份的 X.509 证书,并且客户端必须信任此服务器证书。而客户端同样要提供一个有效的证书,来证明自己的身份。 这里使用http协议。建议安全上下文以后,使用共享安全上下文对SOAP消息进行加密和签名。使用证书对客户端和服务进行身份验证。也就是客户端提供有效证书才可以访问此服务。
1.身份验证(服务器):提供证书,(使用 HTTP)用于初始会话协商和证明服务身份。 
2.身份验证(客户端):客户端证书进行身份验证
   WCF消息安全模式之证书身份验证的架构如下:
    客户端建立TLS安全上下文以后,会使用商定的密码对消息签名,客户端使用证书加密数据,服务端使用证书解密数据,保证数据的安全和机密性,消息签名放置被篡改。
   这里客户端提供的是有效的证书,服务器端进行验证。
   下面是制作证书的过程,和传输安全模式的过程一样,这里直接使用相同证书制作工具,新启用端口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,你会看到刚才制作的证书。这个可以查看部分证书,但是功能有限。我们还是使用控制台证书管理工具。
 
 (3)使用MMC建立证书控制单元查看证书的信息:
  开始--运行--MMC--控制台--添加删除单元--证书--当前用户和计算机各添加一个。能查看和管理CurrentUser和LocalMachine的证书。如图:
(4)导入证书到信任的人和信任的CA机构里。步骤如下:
    1.导出证书文件,带密钥的pfx文件。使用mmc,保存到桌面位置(方便查找)。这里记住你制作证书的密码。要使用。
    2.导入证书到信任的人。使用任务-导入向导--选择证书文件,导入即可。
    3.导入证书到信任的机构,使用任务-导入向导--选择证书文件,导入即可。这个证书就被信任了。
【3】服务端配置:
   服务器证书配置完成以后,我们来配置服务端相关的文件,这里简单。也可以使用代码来完成。
    (1)服务类定义:
    重复使用以前定义的服务类代码。 这里服务类就一个方法就是更具用户的name来打印调用时间,代码如下:
//1.服务契约 
        [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; 
                } 
        }

    (2)消息安全模式配置:
       使用消息安全模式,采用客户端证书身份验证策略,Message安全模式下的证书验证方式配置信息如下:
<wsHttpBinding> 
            <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 配置一样,具体代码如下:
behaviors> 
            <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>
   这里指定了服务端证书的查找位置和查找条件,我们证书存储在LocalMachine 个人区域。使用标题进行查找。如果相同标题,需要制定唯一的查找条件。保证查找证书的唯一性。否则会出异常。
   (4)这里我们不需要使用Https传输协议,直接使用http协议即可,服务终结点的配置信息如下:
<services> 
            <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>
   我们的服务元数据终结点使用基地址:http://localhost:8001/
【4】客户端配置:
    这个过程和之前的传输安全模式下,参考WCF分布式安全开发实践(5):传输安全模式之Certificate身份验证:Transport_Certificate_WSHttpBinding , 添加服务的过程一样。直接引用。
    (1)引用元数据:
    因为服务的元数据交换节点启用了Http协议,我们在客户端项目添加元数据地址http://localhost:8001/mex查找服务信息的时候,界面如下:
   继续就会添加完毕服务引用。过程和普通的添加服务元数据引用一样,会产生客户端相关代码文件。输入命名空间,现在我们点击Ok。等待完成即可。   
    (2)配置文件:
    客户端配置文件使用默认设置,主要是安全模式的设置要如下,与服务端匹配。使用证书验证方式。
bindings> 
                        <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>
    (3)客户端证书:
        这里我们要在配置文件里提供客户端的证书,也可以采用代码方式提供客户端证书。配置文件的方式比较简单。
直接在endpointBehaviors里设置以后,应用到终结点行为配置上就可以了。代码如下:
<behaviors> 
<endpointBehaviors> 
                    <behavior name="endpointBehavior"> 
                        <clientCredentials> 
                            <clientCertificate storeName="My" 
                                                                 x509FindType="FindBySubjectName" 
                                                                 findValue="WCFClientPK" 
                                                                 storeLocation="CurrentUser"/> 
                        </clientCredentials> 
                    </behavior> 
                </endpointBehaviors> 
            </behaviors> 
    (4)测试代码:
      等待代码生成结束,我们这里就直接生成客户端代理类的实例来调用服务进行测试。这里客户端在调用服务以前,必须信任证书,这里我们使用了一段通用的代码,来建立TLS使用。这里会信任服务器的证书。代码如下:
public static class Util 
        { 
                /// <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; 
                } 
        }

   客户端测试代码很简单,我们不需要提供客户端证书了,因为配置文件里已经设置完毕。接下来就是通过客户端代理来调用WCF服务。代码如下:
static void Main(string[] args) 
                {

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是导出的客户端证书的文件,包含密钥,密码为保护密码。

  (4)测试结果:
   启动宿主程序,然后启动客户端程序,客户端成功调用服务,宿主打印的消息。如图:
【5】总结
     Windows Communication Foundation (WCF) 服务和客户端。WCF安全机制都是依赖现有的安全体系和框架来完成的。这里的消息安全模式下的客户端证书身份验证,其实没有太大的变化。就是使用证书来验证客户端的有效性,合法性。
   (1)服务器需要一个证明服务器身份和有效的可用于TLS传输层安全的 X.509 证书,并且客户端必须信任此服务器证书。
   (2)客户端提交证书的方式与传输安全之证书验证方式一样,服务器端需要提供证书,但是不需要httpcfg.exe设置。
   (3)初始协商需要服务器证书来建立TLS连接,协商完毕以后,建立共享安全上下文,这里使用商定的加密算法对SOAP消息进行加密和签名。
   (4)如果你启用协商,而不把服务器证书在客户端设置信任,导入信任的办法机构,会出现SOAP安全协商失败的异常。
   (5)这里客户端调用WCF服务以前要提供提供了有效的证书,和Transport安全模式的证书验证方式类似。差别只是在于安全机制,前者使用的是HTTPS来保证通信安全,后者采用TLS。相同的地方都是在建立连接之前进行客户端证书身份验证。
   (6)参考代码: 
/Files/frank_xl/8.1.WCFServiceSecurityDemoFrankXuLei_Message_Certificate_WSHttpBinding.rar
   以上基本是消息安全之证书验证方式的实现过程。相比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>身份验证的更多相关文章

  1. WCF身份验证二:基于消息安全模式的自定义身份验证

    使用X509证书进行身份验证应该说是WCF安全模型中最”正常”的做法, 因为WCF强制要求使用证书加密身份数据, 离开了证书, 所有的身份验证机制拒绝工作, WCF支持的身份验证机制也相当复杂, 这里 ...

  2. WCF 学习总结5 -- 消息拦截实现用户名验证(转)

    WCF建立在基于消息的通信这一概念基础上.通过方法调用(Method Call)形式体现的服务访问需要转化成具体的消息,并通过相应的编码(Encoding)才能通过传输通道发送到服务端:服务操作执行的 ...

  3. (WCF初体验)WCF的认证和消息保护

    最近做WCF开发,有个需求是在服务端做认证,网上查资料了解到可以用UserName和Password 来做认证,只需要写好配置文件和在服务端写好验证类就行了,但是网上普遍的博文都是需要用证书,而我自己 ...

  4. 两步验证杀手锏:Java 接入 Google 身份验证器实战

    两步验证 大家应该对两步验证都熟悉吧?如苹果有自带的两步验证策略,防止用户账号密码被盗而锁定手机进行敲诈,这种例子屡见不鲜,所以苹果都建议大家开启两步验证的. Google 的身份验证器一般也是用于登 ...

  5. WCF分布式开发步步为赢(13):WCF服务离线操作与消息队列MSMQ

    之前曾经写过一个关于MSMQ消息队列的文章:WCF分布式开发必备知识(1):MSMQ消息队列 ,当时的目的也是用它来作为学习WCF 消息队列MSMQ编程的基础文章.在那篇文章里,我们详细介绍了MSMQ ...

  6. [老老实实学WCF] 第十篇 消息通信模式(下) 双工

    老老实实学WCF 第十篇 消息通信模式(下) 双工 在前一篇的学习中,我们了解了单向和请求/应答这两种消息通信模式.我们知道可以通过配置操作协定的IsOneWay属性来改变模式.在这一篇中我们来研究双 ...

  7. Yii 验证和消息

    setFlash(), getFlash()可以完成验证成功后提示 <?php # 成功信息提示 Yii::app()->user->setFlash('success', &quo ...

  8. laravel的Validation检索验证错误消息

    基本用法 处理错误消息 错误消息和视图 可用的验证规则 有条件地添加规则 自定义错误消息 自定义验证规则 基本用法 Laravel提供了一个简单.方便的工具,用于验证数据并通过validation类检 ...

  9. 腾讯消息队列CMQ部署与验证

    环境 IP 备注 192.168.1.66 node1 前置机 192.168.1.110 node2 192.168.1.202 node3 架构图 组件介绍 组件 监听端口 access 1200 ...

随机推荐

  1. C#提取html中的汉字

    using System.Text.RegularExpressions; private string StripHT(string strHtml) //从html中提取纯文本 { Regex r ...

  2. kali linux 中文出现乱码问题的解决

    确定locales已经安装,用”apt-get install locales”命令:之后可用”locale -a”查看当前系统支持的字符集. 1. 在命令行输入”dpkg-reconfigure l ...

  3. IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/app

    web.xml初始化spring容器出错 org.springframework.beans.factory.BeanDefinitionStoreException: IOException par ...

  4. Java写Excel(不生成实体文件,写为流的形式)

    java 写 Excel(不生成实体文件,写为流的形式) public String exportReportExcel(String mediaCode, List<SimpleMediaRe ...

  5. php Trait的使用

    1.php中的trait是啥? 看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait是一种代 ...

  6. Kubernetes-ELK

    ElasticSearch日志搜集查询和展现案例 容器中输出到控制台的日志都会以*-json.log的命名方式存储在/var/lib/container目录之下: Kubernetes采用Fluent ...

  7. (数据科学学习手札32)Python中re模块的详细介绍

    一.简介 关于正则表达式,我在前一篇(数据科学学习手札31)中已经做了详细介绍,本篇将对Python中自带模块re的常用功能进行总结: re作为Python中专为正则表达式相关功能做出支持的模块,提供 ...

  8. 联想ThinkPad S3-S440虚拟机安装,ubuntu安装,Hadoop(2.7.1)详解及WordCount运行,spark集群搭建

    下载ubuntu操作系统版本 ubuntu-14.10-desktop-amd64.iso(64位) 安装过程出现错误: This kernel requires an X86-64 CPU,but ...

  9. shell eval命令使用

    eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令. 该命令适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两次扫描. 这些需要进行两次扫描的变量有时被称为复杂变量.不过这些变量本 ...

  10. Python的logging模块、os模块、commands模块与sys模块

    一.logging模块 import logging logging.debug('This is debug message') logging.info('This is info message ...