首先安装 服务端安全证书 代码如下: // 下面第一行是安装证书,第二行是将证书列入信任
makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=localhost -sky exchange -pe
certmgr.exe -add -r LocalMachine -s My -c -n localhost -r CurrentUser -s TrustedPeople
安装客户端安全证书代友如下
makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=Client -sky exchange -pe
可以通过运行mmc 在证书列表中将额客户端证书导出和提供下载,要调用服务的各户端安装此客户端证书即可。
关于安装生成WcF代理类的工具- SvcUtil.exe 运行路径C:\Program Files\Microsoft SDKs\Windows\v7.0A\binSvcUtil.exe即可
安将后即可生成 客户端代理类,代码如下:
vs2010版生成非异步的代码如下
svcutil net.tcp://192.168.0.100:3333/ChatService /language:
C# /out:proxy.cs /config:app.config
vs2010版生成异步的代码如下
svcutil net.tcp://192.168.0.100:3333/ChatService /a /language:
C# /out:proxy.cs /config:app.config
VS2012版生成非异步的代码如下
svcutil /language:C# /out:D\Client.cs /config:D\app.config http://169.254.178.26:8181/mywcfUsername?wsdl
Vs2012生成异步的代码如下
svcutil /language:C# /out:D\Client.cs /config:D\app.config http://169.254.178.26:8181/mywcfUsername?wsdl /a
WCF程序中的服务契约代码
namespace WCFUserNameConstract { [ServiceContract] public interface IWcfContract { [OperationContract] bool GetOnWcfService(ref string MessageInfo); } }
WCf 和序中的实现
namespace WcfUserNameService { public class WcfUserNameService : IWcfContract { public bool GetOnWcfService(ref string MessageInfo) { MessageInfo = "调用服务成功了,这是返回来的!"; return true; } } }
WCF中的寄宿配置文件
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <system.serviceModel> <services> <service name="WcfUserNameService.WcfUserNameService" behaviorConfiguration="myBehavior"> <host> <baseAddresses> <add baseAddress="http://localhost:8181/mywcfUsername"/> </baseAddresses> </host> <endpoint address="" binding="wsHttpBinding" contract="WCFUserNameConstract.IWcfContract" bindingConfiguration="myBinding"></endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint> </service> </services> <bindings> <wsHttpBinding> <binding name="myBinding"> <security mode="Message"> <message clientCredentialType="Certificate"/> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="myBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> <serviceCredentials> <!--服务端的验证方式--> <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/> <!--客户端的验证方式--> <clientCertificate> <authentication certificateValidationMode="None"/> </clientCertificate> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
WCF宿主程序代码
namespace WcfUserNameConsole { class Program { static void Main(string[] args) { using (ServiceHost host = new ServiceHost(typeof(WcfUserNameService.WcfUserNameService))) { host.Opened += delegate { Console.WriteLine("服务已启动,按任意键继续……"); }; host.Open(); Console.Read(); host.Close(); } } } }
WCf客户端配置(说明:下面的encodedValue中的值,最好通过上面的SvcUtil.exe 工具先生成客户端代理类和app.config,从生成app.config考出)
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <system.serviceModel> <client> <endpoint address="http://localhost:8181/mywcfUsername" binding="wsHttpBinding" contract="WCFUserNameConstract.IWcfContract" behaviorConfiguration="myBehavior" bindingConfiguration="myBind" name="myEnd"> <identity> <certificate encodedValue="AwAAAAEAAAAUAAAArqroV9p5vtgt1lik21z43G4bfgwgAAAAAQAAADkCAAAwggI1MIIB46ADAgECAhCsu6/GZUD3kUAQ86yeDBvTMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMTQxMDE4MTc0MDM4WhcNMzkxMjMxMjM1OTU5WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqQOFOXTVPbAjRHN+UpYJ76pYq+ZhJHwUl+WL2TBn0l0DqHxZw2MCV/89YnbMycelLk6V2O1xi5aVORDr+wetGacZ7xNBkZtKWJDIlFBCbsc3MohOtXKmODaqp/uj8aWZ3z2+rMMxx2CYOweEMTeZrZfX5wGGkb/OLdfKlJAInH5zgQfz0dy4RB+hZXgKVIoJHS9tkIlaZd1JzUCJu8wr9I6Xjd920UrKyYoqvV6eEkwvSNPUCmSzHHKx5irMmZc1V2MoDWgUMSyF1BgCKspviwjfi3s5uuJMg4JhDtvzL6Vt2hksIT156sfiiB6U9/YaMsJwJhEpwVg4neu2yWhwFAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAG23sBymsfSbOINVpTJj9fJNJFcGaclzlIT3B3H2WZj+nWmjx6zwB6ofZPFDQDHVaXLaL9J1dsw56aXJzN6YJhw==" /> </identity> </endpoint> </client> <bindings> <wsHttpBinding> <binding name="myBind"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" /> <security mode="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="Certificate" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" /> </security> </binding> </wsHttpBinding> </bindings> <behaviors> <endpointBehaviors> <behavior name="myBehavior"> <clientCredentials> <clientCertificate findValue="Client" storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName"/> <serviceCertificate> <authentication certificateValidationMode="None"/> </serviceCertificate> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> </configuration>
WCf客户端调用
namespace MyClient { class Program { static void Main(string[] args) { ChannelFactory<WCFUserNameConstract.IWcfContract> factory = new ChannelFactory<WCFUserNameConstract.IWcfContract>("myEnd"); //UserNamePasswordClientCredential Uinfo = factory.Credentials.UserName; //Uinfo.UserName = "张三"; //Uinfo.Password = "123456"; string MessageInfo = "服务出错了!"; IWcfContract wcf = factory.CreateChannel(); using (wcf as IDisposable) { bool bls = wcf.GetOnWcfService(ref MessageInfo); Console.WriteLine("调用服务" + bls.ToString() + MessageInfo); Console.Read(); } } } }
关于WCF使用安全证书消息加密方式验证及传输的好处:
如果不加密,基本没安全可言,略有点编程常识的人都能获取的到你传输的信息,很容易破译。使用WCF证书验证,双方都传递都使用了消息加密,不易破译,另外证书验证,加强了服客两
端的安全验证,没有证书就调用不了,使程序建立在一个安全性较高的通信线路上通信。