为了更好都做这个实验, 我用了一台VM做客户端,只有两台机才能真正的看出效果 !
主机:192.168.172.1 //客户机192.168.721.230
主机的证书环境和前面几讲一样(因为原来的源码没了,我重新做了一个解决方案)
首先配置主机的配置文件,让只有有证书的客户端才能访问
一般地 behavior 下面设置的是为了让对方验证自己的,而bindings下面的要求对方提供什么来证明自己的身份
主机的C#代码还是和原来一样!
下面一步是关键的一步
在客户端中用 makecert -sr localmachine -ss My -n CN=WCFClientPK -sky exchange -pe –r
建立客户端证书 (这个建立在个人证书下面, 经测试没有必要把把放到可信任的机构中去! )
把证书导出,请选择不要导出私钥, 假设假出文件名为Client.cer
对Client.cer复制到主机上,且把它导入到个人,还可信任的CA中去(这有点自欺欺人,哈哈!)
然后配置客户 ,按前几课讲的方法 更新一个 service reference 然后做如下修改
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> <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" proxyCredentialType="None" realm="" /> <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="https://192.168.172.1:99/myWCF" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="WCFHost.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="MyClientBehavior"/> </client> <!--这里加上要传到主机上进行验证的证书 ,可以直接用证书文件--> <behaviors > <endpointBehaviors > <behavior name ="MyClientBehavior"> <clientCredentials> <clientCertificate storeName="My" x509FindType="FindBySubjectName" findValue="WCFClientPK" storeLocation="LocalMachine"/> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration>
客户端的C#代码没什么改变
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; namespace WCFClient { class Program { static void Main(string[] args) { WCFHost.Service1Client client = new WCFClient.WCFHost.Service1Client(); //client.ClientCredentials.UserName.UserName = "Asen"; //client.ClientCredentials.UserName.Password = "Asen"; //为什么这里把服务器的证书导到客户端,这个信任还是不存在呢? System.Net.ServicePointManager.ServerCertificateValidationCallback += myCertificateValidate; Console.Write(client.GetData("客戶端傳過去的值!")); 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; } } }
至此一个通过证书来访问WCF的客户端口测试做完了!
关键的一步就是要把证书让服务器信任!
<?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.172.1:99/" /> </baseAddresses> </host> <endpoint address ="myWCF" binding="wsHttpBinding" contract="WCF.IService1" bindingConfiguration="mywsHttpBindings"> </endpoint> <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="WCF.Service1Behavior"> <serviceMetadata httpsGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="False" /> <!--下面添加服务器证书 这一部分加了有什么用,现在还不清楚 ,原以为是为了让客户信任的,结果把服务器证书导到客户端,结果还是强制信任--> <serviceCredentials> <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="WCFServerPK" storeLocation="LocalMachine"/> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding><!--这里还是wsHttpBinding--> <binding name ="mywsHttpBindings" > <security mode ="Transport"> <transport clientCredentialType ="Certificate"/><!--************把验证方式由原来第一讲的无验证改为证书验证--> </security> </binding> </wsHttpBinding> </bindings> </system.serviceModel> </configuration>
浙公网安备 33010602011771号