说明 :很多东西引用自老徐的博客
请注意下面这一部门是以后学习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改成如下:
WCF
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(string value);
}
}
改Service1.cs:
WCF
{
public class Service1 : IService1
{
public string GetData(string value)
{
return string.Format("WCF Server Return :", value);
}
}
}
二,新加一个WCF 宿主:(ConsoleApplication命名为:WCFHost)
把WCF工程里的App.config(配置文件)复制到这个工程中,做如下说明的修改
<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服务监听
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 引用
客户代码如下:(请注意重写证验证的那部分方法)
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就算完成了,在这里没有了客户端的验证过程 ,这个以后的内容中将会讲到