一:创建证书
makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=TestServer -sky exchange -pe
二;建立wcf服务
配置文件:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mybehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<clientCertificate>
<!--自定义对客户端进行证书认证方式 这里为 None-->
<authentication certificateValidationMode="None"/>
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfCertificate.Validator,WcfCertificate" />
<serviceCertificate storeLocation="LocalMachine" storeName="My" findValue="TestServer" x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<!--指定验证方式-->
<bindings>
<wsHttpBinding>
<binding name="myhttpbind">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="WcfCertificate.Service1" behaviorConfiguration="mybehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="myhttpbind" contract="WcfCertificate.IService1">
<identity>
<dns value="TestServer"/>
</identity>
</endpoint>
<endpoint address="MEX" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
三:增加一个自定义验证类
Validator类,它要继承System.IdentityModel.Selector.UserNamePasswordValidator基类。
public class Validator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (!string.Equals(userName, "sa") || !string.Equals(password, "1234"))
throw new Exception("Access Denied");
}
}
四:前端调用
配置文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.1.102:8191/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
name="WSHttpBinding_IService1" behaviorConfiguration="mye">
<identity>
<dns value="TestServer" />
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="mye">
<clientCredentials>
<serviceCertificate>
<!--这里必须要制定为None-->
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
调用时需要知道用户名密码
private void button1_Click(object sender, EventArgs e)
{
ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
sc.ClientCredentials.UserName.UserName = "sa";
sc.ClientCredentials.UserName.Password = "1234";
MessageBox.Show(sc.GetData(22));
}