1.Host 配置信息
Message 安全模式配置
<bindings> <wsHttpBinding> <binding name="MessageAndUserName" > <!--安全模式 为 Message --> <security mode="Message"> <transport clientCredentialType="None"/> <!--客户端自定义验证 --> <message clientCredentialType="UserName"/> </security> </binding> </wsHttpBinding> </bindings>
行为
<behaviors> <!--服务行为 运行于服务级别,适用于所有端点,负责内容如:实例化、事务、授权、审计 等--> <serviceBehaviors> <behavior name="WCFService.WCFServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> <serviceCredentials> <!-- mmc 命令 文件->添加/删除管理单元->证书->计算机证书 My=个人 查找名称=kfsmqoo 本地计算机 --> <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="kfsmqoo" storeLocation="LocalMachine"/> <clientCertificate > <authentication certificateValidationMode="None" /> </clientCertificate> <!--WCFServiceCert.CustomUserNamePasswordValidator 验证类 WCFServiceCert 命名空间 --> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFServiceCert.CustomUserNamePasswordValidator,WCFServiceCert" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors>
以下是控制台跟xml的相关信息。如果不清楚证书如何生成,请参照 WCF SSL(证书篇)
Host 下面整个 App.config
<?xml version="1.0"?> <configuration> <system.serviceModel> <behaviors> <!--服务行为 运行于服务级别,适用于所有端点,负责内容如:实例化、事务、授权、审计 等--> <serviceBehaviors> <behavior name="WCFService.WCFServiceBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> <serviceCredentials> <!-- mmc 命令 文件->添加/删除管理单元->证书->计算机证书 My=个人 查找名称=kfsmqoo 本地计算机 --> <serviceCertificate storeName="My" x509FindType="FindBySubjectName" findValue="kfsmqoo" storeLocation="LocalMachine"/> <clientCertificate > <authentication certificateValidationMode="None" /> </clientCertificate> <!--WCFServiceCert.CustomUserNamePasswordValidator 验证类 WCFServiceCert 命名空间 --> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFServiceCert.CustomUserNamePasswordValidator,WCFServiceCert" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="MessageAndUserName" > <!--安全模式 为 Message --> <security mode="Message"> <transport clientCredentialType="None"/> <!--客户端自定义验证 --> <message clientCredentialType="UserName"/> </security> </binding> </wsHttpBinding> </bindings> <services> <service behaviorConfiguration="WCFService.WCFServiceBehavior" name="WCFServiceCert.CertService"> <endpoint address="WCFService" binding="wsHttpBinding" bindingConfiguration="MessageAndUserName" contract="WCFServiceCert.ICertService"> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:8001/"/> </baseAddresses> </host> </service> </services> <serviceHostingEnvironment aspNetCompatibilityEnabled="false"/> </system.serviceModel> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration>
2.ServiceContract 信息
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.Text; using System.IO; namespace WCFServiceCert { public class CertService : ICertService { public string GetData() { if (CustomUserNamePasswordValidator.flg_Checked == true) { return "验证通过"; } else { return "验证失败"; } } } [ServiceContract] public interface ICertService { [OperationContract(Name = "GetDataJson")] [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetData", BodyStyle = WebMessageBodyStyle.Bare)] string GetData(); } }
2.1 我们需要继承UserNamePasswordValidator 类,服务端Message模式需要引用 DLL
DLL 如下:
System.IdentityModel.dll
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; // <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFServiceCert.CustomUserNamePasswordValidator,WCFServiceCert" /> namespace WCFServiceCert { public class CustomUserNamePasswordValidator : UserNamePasswordValidator { public static bool flg_Checked { get; set; }
public override void Validate(string userName, string password) { if (userName == "kfsmqoo" && password == "123456") { flg_Checked = true; Console.WriteLine("验证成功!"); } else { flg_Checked = false; Console.WriteLine("验证失败!"); } } } }
3.2 Client 端生成的app.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_ICertService" 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="Message"> <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost:8001/WCFService" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICertService" contract="Wcf_CustomService.ICertService" name="WSHttpBinding_ICertService"> <identity> <!--客户端验证服务器的证书的编码表示形式 Base64--> <certificate encodedValue="AwAAAAEAAAAUAAAAvETLK3VQgp807ib52Hz0oQnQ0a4gAAAAAQAAAOwBAAAwggHoMIIBVaADAgECAhABEysIfmRhrUSM1FZxeuI5MAkGBSsOAwIdBQAwEjEQMA4GA1UEAxMHa2ZzbXFvbzAeFw0xNDA2MjMwMDI3MzJaFw0zOTEyMzEyMzU5NTlaMBIxEDAOBgNVBAMTB2tmc21xb28wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMX8IcsAvfSEoWcsl9b5QkEal5lk4Ml9uhFAxUApTScSwwhawyo02uNn7vw+Om6vZuupif+mzmhqZTf6t1R1s40x64gT4QjylRPFC212ZP7nQqekdUTWIIoVetb0tpkz0Anzvfe1DjDseTlTpryC6suk6/4pFPqYmUoLPFoa3eeNAgMBAAGjRzBFMEMGA1UdAQQ8MDqAEHEoWyOCGoKd77RjPKjbIjGhFDASMRAwDgYDVQQDEwdrZnNtcW9vghABEysIfmRhrUSM1FZxeuI5MAkGBSsOAwIdBQADgYEAK0tVy8ONNoQxWCFQolRAYbAZf0naY6aiyTnBEsf4aHgifK1J3A98TXoZZJV4qsEvmoBF9pEUa2KwGdit8hL3rDp/Z5JLzsabbBEc+IkK3N5VMzUTJwHCQl1P5mQX8+RdYL3xLkKqq9s6vGBi1t2v8BNzUZK41tjtJaXhlNckGbU=" /> </identity> </endpoint> </client> </system.serviceModel> </configuration>
3.3 客户端代码 和服务器的返回结果。
Wcf_CustomService.CertServiceClient client = new Wcf_CustomService.CertServiceClient(); client.ClientCredentials.UserName.UserName = "abc"; client.ClientCredentials.UserName.Password = "123456"; MessageBox.Show(client.GetDataJson()); Wcf_CustomService.CertServiceClient client1 = new Wcf_CustomService.CertServiceClient(); client1.ClientCredentials.UserName.UserName = "kfsmqoo"; client1.ClientCredentials.UserName.Password = "123456"; MessageBox.Show(client1.GetDataJson());
看看服务器的返回信息。
代码下载