【转】x.509证书在WCF中的应用(CS篇)

【转自】x.509证书在WCF中的应用(CS篇)

 

 

为什么要用x.509证书?
WCF的服务端和客户端之间,如 果不作任何安全处理(即服务端的<security mode="None">),则所有传输的消息将以明文方式满天飞,在internet/intranet环境下无疑是很不安全的,这就是用证书的 目的。(当然WCF还有其它安全机制,比如最常见的UserName方式,但通常每次都要从数据库读取用户名/密码信息进行验证,比较麻烦,开销也大,个 人觉得还是证书最为方便)--关于x.509证书

的基本知识,可参见http://www.cnblogs.com/yjmyzz/archive/2008/08/19/1271171.html

大致原理(个人理解,可能不太准确):
正确设置服务端与客户端证书后,WCF的服务端启动时,需要利用服务端证书验证,如果验证通过将正常启动,否则报异常,同时客户端调用服务端方法时,也需要提供客户端证书,服务端接受到客户端证书后,验证客户端证书的有效性,如果通过,则允许客户端正常调用。

 

下面将逐步讲解如何使用:

1.制作证书

先进入到vs2008的命令行状态,即:
开始-->程序-->Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示

键入:

makecert -r -pe -n "CN=MyServer" -ss My -sky exchange

解释一下:makecert.exe是一个专门用来制作证书的小工具,上面一行的意思就是制作一个CN=MyServer的服务器证书,默认存储在CurrentUser"My这个位置,同时这个证书标识为可导出。(详细的

MakeCert参数可参见http://msdn.microsoft.com/zh-cn/bfsktky3(vs.80).aspx)

再输入:

makecert -r -pe -n "CN=MyClient" -ss My -sky exchange

生成客户端证书,证书生成好以后,可以在IE里查看到,IE-->工具-->Internet选项-->内容-->证书

同时如何管理已经安装的证书,可参见http://www.cnblogs.com/yjmyzz/archive/2008/08/20/1272128.html

2.wcf服务端

vs.net2008启动后,新建一个控制台应用程序-->(右击)添加-->新建项-->WCF服务-->命名为MyService.cs-->保存

保存后,系统会自动生成一个接口文件IMyService.cs

二个文件的内容如下:
IMyService.cs

using System;  
using System.ServiceModel;

namespace Server
{
    
// 注意: 如果更改此处的接口名称 "IMyService",也必须更新 App.config 中对 "IMyService" 的引用。
    [ServiceContract]
    
public interface IMyService
    {
        [OperationContract]
        
string Test();

    }
}


MyService.cs

using System; 
using System.ServiceModel;
namespace Server
{
    
// 注意: 如果更改此处的类名 "MyService",也必须更新 App.config 中对 "MyService" 的引用。
    public class MyService : IMyService
    {
        
public string Test()
        {
            Console.WriteLine(
"服务端输出:"n" + ServiceSecurityContext.Current.PrimaryIdentity.AuthenticationType);
            Console.WriteLine(ServiceSecurityContext.Current.PrimaryIdentity.Name);
            
return "服务端时间:" + DateTime.Now.ToString(); 
        }
    }
}

再来新建一个cs文件:CustomX509CertificateValidator.cs
内容先贴在下面

using System;
using System.Security.Cryptography.X509Certificates;
using System.IdentityModel.Tokens;
using System.IdentityModel.Selectors;

namespace Server
{
    
public class CustomX509CertificateValidator : X509CertificateValidator
    {
        
public override void Validate(X509Certificate2 certificate)
        {
            Console.WriteLine(certificate.Subject);
            Console.WriteLine(certificate.Thumbprint); 
            
if (certificate.Thumbprint != "3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF")
                
throw new SecurityTokenException("Certificate Validation Error!");
        }
    }
}

 

注意:项目必须先添加对System.IdentityModel的引用

解释一下:
这个文件的用户是:客户端要调用服务端方法,并提供客户端证书时,用来验证客户端证书的有效性。注意里面的if (certificate.Thumbprint != "3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF")这一句,大家调试的时候,里面的 3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF要换成你自己的客户端证书的信息(每一个证书对应的这一串字符都是唯 一的),可通过在IE浏览器里,查看MyClient证书的详细信息得到,见下图:


同时注意配置文件App.Config,内容如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    
<system.serviceModel>
        
<behaviors>
            
<serviceBehaviors>
                
<behavior name="Server.MyServiceBehavior">
                  
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080" />
                  
<serviceDebug includeExceptionDetailInFaults="true" />
                  
<serviceCredentials>
                    
<clientCertificate>
                      
<authentication certificateValidationMode="Custom" customCertificateValidatorType="Server.CustomX509CertificateValidator,Server"/>
                    
</clientCertificate>
                    
<serviceCertificate findValue="MyServer" storeLocation="CurrentUser"
                      x509FindType
="FindBySubjectName" />
                  
</serviceCredentials>
                
</behavior>
            
</serviceBehaviors>
        
</behaviors>
      
<bindings>
        
<netTcpBinding>
          
<binding name="NewBinding0">
            
<security mode="Transport">
              
<transport clientCredentialType="Certificate" />
            
</security>
          
</binding>
        
</netTcpBinding>
      
</bindings>
        
<services>
            
<service behaviorConfiguration="Server.MyServiceBehavior" name="Server.MyService">
                
<endpoint address="net.tcp://localhost:8081" binding="netTcpBinding" contract="Server.IMyService" bindingConfiguration="NewBinding0"/>              
            
</service>
        
</services>
    
</system.serviceModel>
</configuration>

 

解释一下:
<authentication certificateValidationMode="Custom" customCertificateValidatorType="Server.CustomX509CertificateValidator,Server"/></clientCertificate>
这一行的意思就是通知WCF服务端,验证客户端证书的模式为自定义,验证时调用Server.CustomX509CertificateValidator这个类来完成验证

<serviceCertificate findValue="MyServer" storeLocation="CurrentUser" x509FindType="FindBySubjectName" />
这一行的意思是WCF服务端验证证书时,到CurrentUser这个位置查询CN=MyServer的证书

最后在Program.cs里启用WCF,内容如下:

using System;  
using System.ServiceModel;

namespace Server
{
    
class Program
    {
        
static void Main(string[] args)
        {
            ServiceHost host 
= new ServiceHost(typeof(MyService));
            host.Open();
            Console.ReadKey();
        }
    }
}

 

build一下,如果编译无错的话,服务端完工,可以运行一下,将弹出一个DOS命令窗口(不过什么输出也没有),只要不报错,就表明Ok了,先不要急着关,尝试浏览一下:

http://localhost:8080/(这个地址哪里来的?回头看下App.config,里面有一行<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/" />,呵呵,明白了吧) 正常的话,应该类似下图所示:

3.客户端调用

下面生成服务端的代理和配置文件,客户端开发将用到这二个文件,同样先进入vs2008的命令行状态,输入:

svcutil.exe http://localhost:8080/ /d:c:"123"

注意:输入这一行命令的时候,请确保服务端程序正在运行。这一句的意思就是在c:"123"目录下输出WCF的代理文件和配置文件

打开vs.net2008,再新建一个控制台应用程序,可以命名为Client

把c:"123"下生成的二个文件MyService.cs,output.config添加到Client项目中,同时将output.config改名为App.Config

Progam.cs代码内容如下:

using System; 
namespace Client
{
    
class Program
    {
        
static void Main(string[] args)
        {
            
using (MyServiceClient client = new MyServiceClient())
            {
                Console.WriteLine(
"客户端输出:");
                Console.WriteLine(client.Test());
            } 
            Console.ReadKey();
        }
    }
}

同时,参考下面的内容手动修改一下App.Config文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    
<system.serviceModel>
      
<behaviors>
        
<endpointBehaviors>
          
<behavior name="NewBehavior">
            
<clientCredentials>
              
<clientCertificate findValue="MyClient" x509FindType="FindBySubjectName"/>
              
<serviceCertificate>
                
<authentication certificateValidationMode="None" />
              
</serviceCertificate>
            
</clientCredentials>
          
</behavior>
        
</endpointBehaviors>
      
</behaviors>
      
<bindings>
            
<netTcpBinding>
                
<binding name="NetTcpBinding_IMyService" closeTimeout="00:01:00"
                    openTimeout
="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    transactionFlow
="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                    hostNameComparisonMode
="StrongWildcard" listenBacklog="10"
                    maxBufferPoolSize
="524288" maxBufferSize="65536" maxConnections="10"
                    maxReceivedMessageSize
="65536">
                    
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead
="4096" maxNameTableCharCount="16384" />
                    
<reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled
="false" />
                    
<security mode="Transport">
                        
<transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign" />
                        
<message clientCredentialType="Windows" />
                    
</security>
                
</binding>
            
</netTcpBinding>
        
</bindings>
        
<client>
            
<endpoint address="net.tcp://localhost:8081/" binding="netTcpBinding"
                bindingConfiguration
="NetTcpBinding_IMyService" contract="IMyService"
                name
="NetTcpBinding_IMyService" behaviorConfiguration="NewBehavior">
                
<identity>
                    
<dns value="MyServer" />
                
</identity>
            
</endpoint>
        
</client>
    
</system.serviceModel>
</configuration>

 

主要是增加了一个节点
<behaviors>
        <endpointBehaviors>
          <behavior name="NewBehavior">
            <clientCredentials>
              <clientCertificate findValue="MyClient" x509FindType="FindBySubjectName"/>
              <serviceCertificate>
                <authentication certificateValidationMode="None" />
              </serviceCertificate>
            </clientCredentials>
          </behavior>
        </endpointBehaviors>
      </behaviors>

上面红色的行,就是表明客户端调用时,将用MyClient证书来验证

 

同时<endpoint address="net.tcp://localhost:8081/" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IMyService" contract="IMyService"
                name="NetTcpBinding_IMyService" behaviorConfiguration="NewBehavior">这一句,增加了behaviorConfiguration="NewBehavior"

好了,Build一下,没有问题的话,开发完成


4.测试:
先启动服务端,再启动客户端,运行结果如下:

(转贴请注明来自"菩提树下的杨过") http://www.cnblogs.com/yjmyzz/archive/2008/08/20/1272550.html

 

注意服务端server.exe输出的信息中3E4D4B64A90810B6CFF9B1DD2390D8C9488747BF与客户端证书完全吻合

最后来谈谈分发问题,上面这一系列测试都是在同一台机器完成的,客户端总不可能总是跟服务端在一台机器上,这个好办,在IE里把MyClient证书导出,注意导出时要选择"是,导出私钥",然后把导出的pfx文件连同客户端程序一起分发到目标客户机即可,这里要注意几点:

a.客户端上的App.config里,要把<endpoint address="net.tcp://localhost:8081/" 中的localhost换成服务端的Ip地址
b.注意防火墙参数设置(本例中,即要把tcp:8081端口打开)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从概念到案例:初学者须知的十大机器学习算法

本文先为初学者介绍了必知的十大机器学习&#xff08;ML&#xff09;算法&#xff0c;并且我们通过一些图解和实例生动地解释这些基本机器学习的概念。我们希望本文能为理解机器学习基本算法提供简单易读的入门概念。 机器学习模型 在《哈佛商业评论》发表「数据科学家是 21 世…

测试Live Write的插件

1、文字竖排&#xff1a; 删除&#xff0c;只因首页显示时太占空间。2、酷表情&#xff1a;3、Rhapsody SongI am listening to Sad Songs And Waltzes by Cake . Rhapsody.

手把手教你用7行代码实现微信聊天机器人 -- Python wxpy

环境要求&#xff1a; Windows / Linux / Mac OS Python 3.4-3.6&#xff0c;以及 2.7 版本 wxpy安装 ## 使用国内源安装速度快 pip install -U wxpy -i "https://pypi.doubanio.com/simple/" 实例 让机器人与所有好友聊天 from wxpy import * # 实例化&#xff0c;并…

Dapr 已在塔架就位 将发射新一代微服务

微服务是云原生架构的核心&#xff0c;通常使用Kubernetes 来按需管理服务扩展。微软一直走在 Cloud Native Computing Foundation的 最前沿&#xff0c;并通过使用Kubernetes来支持其超大规模Azure和其混合云Azure Stack&#xff0c;微软对云原生的投资一部分来自其工具&#…

python 复制文件_10 行 Python 代码写 1 个 USB 病毒

(给Python开发者加星标&#xff0c;提升Python技能)转自&#xff1a; 知乎-DeepWeaver昨天在上厕所的时候突发奇想&#xff0c;当你把usb插进去的时候&#xff0c;能不能自动执行usb上的程序。查了一下&#xff0c;发现只有windows上可以&#xff0c;具体的大家也可以搜索(搜索…

html5中外描边怎么写,CSS3实现文字描边的2种方法(小结)

问题最近遇到一个需求&#xff0c;需要实现文字的描边效果&#xff0c;如下图解决方法一首先想到去看CSS3有没有什么属性可以实现&#xff0c;后来被我找到了text-stroke该属性是一个复合属性&#xff0c;可以设置文字宽度和文字描边颜色该属性使用很简单&#xff1a;text-stro…

混凝土墙开洞_满城混凝土柱子切割资质齐全

满城混凝土柱子切割资质齐全专业楼板切割开洞&#xff0c;钢筋混凝土墙开门&#xff0c;开窗&#xff0c;开方洞。混泥土承重墙新开门洞、开窗、通风管道开洞、专业开楼梯口&#xff0c;楼梯口加固&#xff0c;地下室开门洞&#xff0c;水泥墙开门加固、楼板加固、砖墙开门开窗…

马云害怕的事还是发生了

当前&#xff0c;余额宝的收益维持在4%左右不能突破&#xff0c;只能用作“钱包”放点零钱了。 放银行或者余额宝收益偏低&#xff0c;股票市场又处于震荡周期&#xff0c;期货市场等不是普通人进得去的&#xff0c;还不如直接买较高收益的互联网理财产品。 比如屡受政策利好…

cmosfixr插件怎么用_3dmax插件神器|怎么用3dmax插件神器去完成背景墙的效果图设计?...

又到3dmax插件神器的小课堂时间了&#xff01;小伙伴们还记得之前几张的知识点吗&#xff1f;如果不记得自己去温习&#xff0c;温故而知新哦&#xff01;如果学会了&#xff0c;下面学习3dmax插件神器小技巧的第四章建模篇的第4.16小节&#xff1a;怎么用3dmax插件神器去完成背…

不懂这25个名词,好意思说你懂大数据?

如果你刚接触大数据&#xff0c;你可能会觉得这个领域很难以理解&#xff0c;无从下手。近日&#xff0c;Ramesh Dontha在DataConomy上连发两篇文章&#xff0c;扼要而全面地介绍了关于大数据的75个核心术语&#xff0c;这不仅是大数据初学者很好的入门资料&#xff0c;对于高阶…

ab压力测试_Apache ab压力测试的知识点

Apache-ab是著名的Web服务器软件Apache附带的一个小工具&#xff0c;它可以模拟多个并发请求&#xff0c;测试服务器的最大承载压力。ab 是apachebench的缩写,ab命令会创建多个并发访问线程&#xff0c;模拟多个访问者同时对某一URL地址进行访问。它的测试目标是基于URL的&…

现代云原生设计理念

前文传送门什么是云原生&#xff1f;现代设计理念你会如何设计云原生应用程序&#xff1f;需要遵循哪些原则、模式和最佳实践&#xff1f;需要特别关注哪些底层/操作&#xff1f;十二要素应用程序目前被普遍认可的基于云的方法论是"十二要素应用程序"&#xff0c;它给…

NFS服务器架设篇

大家好&#xff0c;本周我们的课程是NFS服务器的架设。下面我们分几个部分来介绍NFS服务器。一、NFS简介NFS是分布式计算机系统的一部分&#xff0c;一般在用unix和类unix的系统上实现文件的传输。而且可以把NFS服务器共享的目录挂载到本地&#xff0c;使用cp&#xff0c;cd&am…

用画小狗的方法来解释Java中的值传递

在开始看我画小狗之前&#xff0c;咱们先来看道很简单的题目&#xff1a; 下面程序的输出是什么&#xff1f; 如果你的回答是“小强”&#xff0c;好&#xff0c;恭喜你答对了。下面我们改一下代码&#xff1a; 是的&#xff0c;我只是在changeName方法里面加了一句代码 这一次…

gif分解工具_Python之GIF图倒放,沙雕快乐源泉

GIF图现在已经融入了我们的日常网络生活&#xff0c;微信群、QQ群、朋友圈......一言不合就斗图&#xff0c;你怕了吗&#xff1f;不用担心&#xff0c;只要学会了Python之GIF倒放技能&#xff0c;你就是“斗图王”。咱们直接开始本文的内容&#xff01;使用的工具1PIL(Python …

微软亚洲研究院全球院友线上欢聚,共话新春

金鼠辞旧岁&#xff0c;金牛报春时&#xff1b;万象正更新&#xff0c;乾坤喜气多。西雅图时间 2 月 6 日&#xff0c;北京时间 2 月 7 日&#xff0c;由微软亚洲研究院院友会西雅图分会主办的“牛转新运”院友新春线上茶话会圆满落幕。重量级嘉宾沈向洋、洪小文、张亚勤、张宏…

从串行线程封闭到对象池、线程池

今天讲一个牛逼而实用的概念&#xff0c;串行线程封闭。对象池是串行线程封闭的典型应用场景&#xff1b;线程池糅合了对象池技术&#xff0c;但核心实现不依赖于对象池&#xff0c;很容易产生误会。 本文从串行线程封闭和对象池入手&#xff0c;最后通过源码分析线程池的核心原…

netty springmvc_springmvc源码架构解析之HandlerMapping

说在前面前期回顾sharding-jdbc源码解析 更新完毕spring源码解析 更新完毕spring-mvc源码解析 更新完毕spring-tx源码解析 更新完毕spring-boot源码解析 更新完毕rocketmq源码解析 更新完毕dubbbo源码解析 更新完毕netty源码解析 更新完毕spring源码架构更新完毕springmvc源码架…

腾讯牛逼,我酸了!!

阅读本文大概需要8分钟。腾讯这两天搞了个业内爆炸沸腾的事情&#xff1a;全员阳光普照发放100股&#xff0c;解禁期一年。腾讯股价近年来一直在疯狂上涨&#xff0c;100股折合人民币6万多&#xff1a;关键是员工什么都没做&#xff0c;直接拿到价值6万的股票。作用可以说是相当…

这本造价500万的“黑科技”日历,用377张爆美插画给你365天理想生活

以前&#xff0c;每个人家里&#xff0c; 都挂着一本日历。 爷爷戴着老花镜&#xff0c; 盘看着黄道吉日&#xff1b; 奶奶一字一句&#xff0c; 念叨着每日禁忌&#xff1b; 我们跟着日历过日子&#xff0c; 时光缓慢&#xff0c;记忆清晰。 那时候&#xff0c;日历本上的日子…