说明 :很多东西引用自老徐的博客
请注意下面这一部门是以后学习WCF安全的基础
一,制作证书
前面讲过一个在于数字证书的,它要用的是一个证书服务器去颁发证书 ,这里用的是一个制作证书的工具 makecert.exe
请注意:不要用这个路径下面的C:\Program Files\Microsoft Visual Studio 9.0\SmartDevices\SDK\SDKTools
而要用C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 路径下面的makecert.exe 为了方便把makecert.exe 拷到了H:\cer下面
制作证书 打开CMD 如下图执行
makecert -sr localmachine -ss My -n CN=WCFServerPK -sky exchange -pe -r
此时打MMC,添加一个证书控制台,会看到如下的界面面,(123和上图的123相对应)
此时的证书是未信任的(看上面右图的那个XX),要把证书添加到受信任根证书颁发机构,这个证书就被信任了!
有两种方法:1,选中证书右键复制 ,到受信任根证书颁发机构的证书目录里执行粘贴(那个右图的那个XX就会消失)
2,通过导出带私钥的证书(请记住要输入的密码),然后再导入到受信任根证书颁发机构的证书目录里,效果同上
一,SSL证书设置
在这里先讲一下HttpCfg.exe / Netsh.exe (为使用的端口SSL注册证书)
Windows Server 2003 或 Windows XP,则使用 HttpCfg.exe 工具。Windows Server 2003 中已安装该工具。下载该工具/Files/frank_xl/HttpcfgFrankXuLei.rar。如果运行的是 Windows Vista,则使用已安装的 Netsh.exe 工具。在Windows\System32目录下。
查询SSL端口证书设置信息:netsh http show sslcert(XP:httpcfg query ssl) 显示如下图(有一个SSL证书):
把这个证书删除:netsh http delete sslcert 192.168.85.1:99
(XP:httpcfg delete ssl –i 192.168.85.1:99 -h 9174185b2860b6d5ec3de133d5fcc4e1419b09e5)
制作SSL证书:netsh http add sslcert ipport=192.168.85.1:99 certhash=8b59064d68ca711670b3c350b2c8eb7bafec27cf appid={00112233-8899-6677-1122-AABBCCEEDDFF}
其中8b59064d68ca711670b3c350b2c8eb7bafec27cf为证书的指纹(证书指纹把中间的空格去掉,请注意如果指纺前面有空间或者tab,也请去掉),{00112233-8899-6677-1122-AABBCCEEDDFF}为任意串
(XP:httpcfg set ssl -i 192.168.85.1:99 -h 8b59064d68ca711670b3c350b2c8eb7bafec27cf)
请注意下面这一部门是以后学习WCF安全的基础
下面开始讲WCF相关的安全知识(有关WCF的基础请看我写的WCF基础这一篇)
通过上面的配置后,开始做后面的操作
一,新建立一个WCF Service Libary ,如下图 ,默认会有一个App.config(配置文件) ,IService1.cs(接口),Service1.cs(实现)
改IService1.cs改成如下:
namespace WCF { [ServiceContract] public interface IService1 { [OperationContract] string GetData(string value); } }
改Service1.cs:
namespace WCF { public class Service1 : IService1 { public string GetData(string value) { return string.Format("WCF Server Return :", value); } } }
二,新加一个WCF 宿主:(ConsoleApplication命名为:WCFHost)
把WCF工程里的App.config(配置文件)复制到这个工程中,做如下说明的修改
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <compilation debug="true" /> </system.web> <system.serviceModel> <services> <service name="WCF.Service1" behaviorConfiguration="WCF.Service1Behavior"> <host> <baseAddresses> <add baseAddress = "https://192.168.85.1:99/" /> <!--把baseAddress 改成那个SSL证书的地址+端口--> </baseAddresses> </host> <endpoint address ="myWCF" binding="wsHttpBinding" contract="WCF.IService1" bindingConfiguration ="mybehaviorConfiguration"> <!--加address ="myWCF" / bindingConfiguration ="mybehaviorConfiguration" 处下面的配置来对应--> <!-- 删除下面的结点-> <!--<identity> <dns value="localhost"/> </identity>--> </endpoint> <!--<endpoint address="mex" binding="mexHttpBinding" 改为 mexHttpsBinding contract="IMetadataExchange"/>--> <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WCF.Service1Behavior"> <serviceMetadata httpsGetEnabled = "True"/> <!-- 把 httpGetEnabled 改为 httpsGetEnabled --> <serviceDebug includeExceptionDetailInFaults="False" /> <!--指定下面服务器证书 开始--> <serviceCredentials > <!--和那个新加证书相对应的--> <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="WCFServerPK" storeLocation="LocalMachine"/> </serviceCredentials> <!--指定下面服务器证书 结束--> </behavior> </serviceBehaviors> </behaviors> <!-- 加上下面的bindings 配置结点 开始 --> <bindings > <wsHttpBinding > <binding name ="mybehaviorConfiguration"> <security mode ="Transport"> <transport clientCredentialType="None"/><!-- 客户端验证为空 --> </security> </binding> </wsHttpBinding> </bindings> <!-- 加上下面的bindings 配置结点 结束--> </system.serviceModel> </configuration>
把System.ServiceModel和前面的那个WCF引用进来,在main 函数里打开WCF服务监听
namespace WCFHost { class Program { static void Main(string[] args) { using (System.ServiceModel.ServiceHost Host = new System.ServiceModel.ServiceHost(typeof(WCF.Service1))) { if (Host.State != System.ServiceModel.CommunicationState.Opened) Host.Open(); Console.Write("WCF SSL 服务打开!!!"); Console.Read(); } } } }
这时候运行WCFHost 就可以打开服务监听
三,新加一个客户端 (ConsoleApplication命名为:WCFClient)
1,编译刚才的WCFHost , 运行bin目录下的WCFHost.exe
2,返回WCFClient 工程 ,右键加一个Add service Reference
在地址栏输入https://192.168.85.1:99/ 或者 https://192.168.85.1:99/mex 前面这部分https://192.168.85.1:99 是SSL证书的地址,要一致,mex 是一个描述服务
如下图,按yes 后输入WCFClient点OK就加入了引用
不知道下面这种为什么不行? (在地址栏输入https://192.168.85.1:99/myWCF 这种却不行!!!!)如下图
3,加进System.Net 引用
客户代码如下:(请注意重写证验证的那部分方法)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net;///////////////// using System.Net.Security;/////////////// using System.Security.Cryptography.X509Certificates;//加上X509证书命名空间 namespace WCFClient { class Program { static void Main(string[] args) { try { WCFServer.Service1Client wcfClient = new WCFClient.WCFServer.Service1Client(); string strReturn = "send to server String !!"; //这下面这一步非常关键,它重写了服务器的验证方法,即不要验证,直接发送请求到服务器端 //重写验证服务端证书的方法。 System.Net.ServicePointManager.ServerCertificateValidationCallback += MyCertificateValidate; strReturn = wcfClient.GetData(strReturn ); Console.Write(strReturn); Console.Read(); } catch (Exception e) { Console.WriteLine("Exception : {0}", e.Message); } Console.WriteLine("Press any key to exit"); Console.Read(); } private static bool MyCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { // trust any certificate!!! System.Console.WriteLine("Warning, trust any certificate"); return true; } } }
至此一个SSL安全的WCF就算完成了,在这里没有了客户端的验证过程 ,这个以后的内容中将会讲到
浙公网安备 33010602011771号