今天继续WCF分布式安全开发实践(5):传输安全模式之Certificate身份验证。本文介绍的内容主要是:主要是传输安全模式的Certificate身份验证方式,基于WSHttpBinding绑定协议的实现过程。主要内容:基本概念,然后是制作证书、SSL证书设置、服务端配置、客户端配置、总结。 【0】传输安全模式之Certificate身份验证: 传输安全模式之Certificate证书身份验证需要服务器需要一个有效的可用于安全套接字层 (SSL) 的 X.509 证书,并且客户端必须信任此服务器证书。 这里使用https协议。客户端提供有效的Certificate证书。 服务器通过证书来检验客户端身份的有效性。
1.身份验证(服务器):提供证书,(使用 HTTPS) 2.身份验证(客户端):提供证书
WCF安全模式Certificate证书身份验证的架构如下:
客户端首先要提供自己的证书,服务器对此进行验证,有效后,服务器会和客户端尝试建立SSL安全套接层,会使用商定的密码对消息签名,客户端使用证书加密 数据,服务端使用证书解密数据,保证数据的安全和机密性,消息签名放置被篡改。这个链接是唯一的。通信结束以后会关闭连接。 是制作和设置SSL证书的过程,和传输安全模式的过程一样,这里直接使用相同证书和端口。延续以前的风格。 【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.导入证书到信任的机构,使用任务-导入向导--选择证书文件,导入即可。这个证书就被信任了。 【2】SSL证书设置: 下面我们来设置SSL端口证书,这个步骤很重要。不然客户端无法查找到WCF服务。 【2.1】查询SSL证书设置: 需要为使用的端口SSL注册证书。Windows Server 2003 或 Windows XP,则使用 HttpCfg.exe 工具。Windows Server 2003 中已安装该工具。下载该工具/Files/frank_xl/HttpcfgFrankXuLei.rar。如果运行的是 Windows Vista,则使用已安装的 Netsh.exe 工具。在Windows\System32目录下。运行此工具需要命令窗口切换到相应工具解压缩目录下,我直接放置到D盘根目录。方便查找。 (1)在 Windows Server 2003 或 Windows XP 中,通过 query 和 ssl 开关使用 HttpCfg.exe 工具查看当前端口配置,在命令窗口切换到HttpCfg在文件目录,你如下面代码: httpcfg query ssl (2)Vista: netsh http show sslcert
查询SSL端口证书设置信息,如图:
 【2.2】设置SSL证书: (1)在 Windows Server 2003 或 Windows XP: httpcfg set ssl -i 0.0.0.0:9001-h 9174185b2860b6d5ec3de133d5fcc4e1419b09e5 (2)Vista: netsh http add sslcert ipport=0.0.0.0:9001 certhash=9174185b2860b6d5ec3de133d5fcc4e1419b09e5 appid={11111111-2222-3333-4444-qqqqqqqqqqqqq} 。最后一个GUID.你可以随便编写一个。使用工具也可以。certhash 参数指定证书的指纹。ipport 参数指定 IP 地址和端口,功能类似于前述 Httpcfg.exe 工具的 -i 开关。appid 参数为可用于标识所属应用程序的 GUID。 【2.3】删除SSL证书: (1)Windows Server 2003 和 Windows XP 中: httpcfg delete ssl -i 0.0.0.0:9001-h 9174185b2860b6d5ec3de133d5fcc4e1419b09e5 (2)Vista: Netsh http delete sslcert ipport=0.0.0.0:9001。 【3】服务端配置: SSL端口证书配置完成以后,我们来配置服务端相关的文件,首先要实现自定义身份验证的代码。我们就要对WCF服务端进行配置,直接使用配置文件,这里简单。也可以使用代码来完成。 (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)传输安全模式配置: 使用传输安全模式,采用客户端Certificate证书身份验证策略,transport安全模式下的Certificate证书验证方式要在客户端基本Certificate证书验证类型下实现。配置信息如下:
<wsHttpBinding> <binding name="BindingConfiguration"> <security mode="Transport"> <transport clientCredentialType="Certificate"/> </security> </binding> </wsHttpBinding>
这个配置要应用到服务的终结点配置上。才会生效。 (4)证书使用: 在服务行为节点属性里配置使用证书WCFServerPK,这个服务器证书就是SSL证书。配置信息如下:
serviceBehaviors> <behavior name="WCFService.WCFServiceBehavior"> <serviceMetadata httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> <serviceCredentials> <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="WCFServerPK" storeLocation="LocalMachine"/> </serviceCredentials> </behavior> </serviceBehaviors>
(5)IE查看元数据: 配置好托管宿主以后,我们就可以启动宿主。然后在浏览器里输入元数据终结点。点击浏览会看到如下界面:
 使用的是https协议, 元数据交互也提供了SSL保护。这里可以点击继续浏览,才能看到服务的信息。如下:
 我们可以在这里点击链接,根据借助svcutil来产生客户端文件。我们这里不做尝试,客户端我们直接在项目里添加引用,借助Visual Studio来完成。 【4】客户端配置: 这个过程和之前的传输安全模式下,添加服务的过程一样。直接引用。 (1)引用元数据: 因为服务的元数据交换节点启用了Https协议,我们在客户端项目添加元数据地址https://computer:9001/mex查找服务信息的时候,会提示SSL证书信息,界面如下:
这个证明我们的服务端证书设置已经起作用,而且是可信的。现在我们点击Yes。继续就会添加完毕服务引用。过程和普通的添加服务元数据引用一样,会产生客户端相关代码文件。输入NameSpace,等待完成即可。 (2)配置文件: 客户端配置文件使用默认设置,主要是安全模式的设置要如下,与服务端匹配。使用证书验证方式。
<security mode="Transport"> <transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" /> </security>
这里我们可以在配置文件里设置证书,WCF客户端会根据配置文件终结点服务行为的证书配置信息来查找客户端证书。 提交给WCF服务端。配置代码如下:
<behaviors> <endpointBehaviors> <behavior name="endpointBehavior"> <clientCredentials> <clientCertificate storeName="My" x509FindType="FindBySubjectName" findValue="WCFClientPK" storeLocation="CurrentUser"/> </clientCredentials> </behavior> </endpointBehaviors> </behaviors>
(3)测试代码: 等待代码生成结束,我们这里就直接生成客户端代理类的实例来调用服务进行测试。这里客户端在调用服务以前,必须提供有效的Certificate证书.使用配置文件设置完毕以后,就可以测试,也可以使用代码来设置证书wcfServiceProxy.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("WCFClientPK.pfx", "password");WCFClientPK.pfx是导出的客户端证书的文件,包含密钥,密码为保护密码。客户端测试代码如下:
WCFClient.ClientProxy.WCFServiceClient clientProxy = new WCFClient.ClientProxy.WCFServiceClient("WSHttpBinding_IWCFService"); //通过代理调用SayHello服务 //wcfServiceProxy.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("user.pfx", "password"); string sName = "Frank Xu Lei Transport UserNamePassword WSHttpBinding"; string sResult = string.Empty; Util.SetCertificatePolicy();//强制信任证书。重写验证服务端证书的方法。 sResult = clientProxy.Hello(sName); Console.WriteLine("Returned Result is {0}", sResult);
(4)测试结果: 启动宿主程序,然后启动客户端程序,稍作等待,Certificate证书无效的时候,服务器验证客户端证书失败,客户端不能调用服务。,当我们提供了有效的Certificate证书的时候,客户端成功调用服务,宿主打印的消息。如图:
 【5】总结 Windows Communication Foundation (WCF) 服务和客户端。服务器需要一个有效的可用于安全套接字层 (SSL) 的 X.509 证书,并且客户端必须信任此服务器证书。 (1) 此处自是在借助传输安全Certificate证书验证方式,客户端提供证书。 (2)客户端要信任服务器证书,服务器验证客户端证书来检验客户端身份的有效性。
|