WCF身份验证及无法找到 X.509 证书的终极解决方案

最近在想WCF身份验证,可遇到不少问题.

在网上看了不少文章都是讲证书验证的,还是照样先生成证书吧

makecert -sr LocalMachine -ss My -n CN=MyServer -sky exchange -pe

注意,这里可能会出现如下类似的错误

Error: Can't create the key of the subject ('bd4f5866-b309-42b6-b58b-8ba355ddbac5')
Failed

解决办法就是先给"C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys"

这个文件夹某些用户的权限,如network service,aspnet,iusr_machinename等

你可以进入证书管理控件台(在mmc中添加"证书"控制单元)查看证书是否成功添加

如果证书为不信任证书,你可将生成的证书导出一份后导入到"受信任的根证书颁发机构"中.

到此证书已生成好了

1.先写个WCF服务吧

代码
[ServiceContract]
public interface IRSQLHepler
{
[OperationContract]
object GetSingle(string SQLString);
[OperationContract]
int ExecuteSql(string SQLString);
[OperationContract]
DataSet Query(
string strSQL, CommandType cmdType, params SqlParameter[] parameters);
}

public class RSQLHepler : IRSQLHepler
{
public int ExecuteSql(string SQLString)
{
}
public object GetSingle(string SQLString)
{
}
public DataSet Query(string strSQL, CommandType cmdType, params SqlParameter[] parameters)
{
}
}

2.想采用用户身份验证,实现抽象类UserNamePasswordValidator

代码
public class CustomUserPassword : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{

}
}

3.服务器配置

代码
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="EndpointBinding">
<security mode="Message">
<transport clientCredentialType="None"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="RemoteSQLHelper.RSQLHeplerBehavior"
name
="RemoteSQLHelper.RSQLHepler">
<endpoint address="" binding="wsHttpBinding" contract="RemoteSQLHelper.IRSQLHepler" bindingConfiguration="EndpointBinding">
<identity>
<dns value="MyServer" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RemoteSQLHelper.RSQLHeplerBehavior">
<!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点-->
<serviceMetadata httpGetEnabled="true"/>
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息-->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="None"/>
</clientCertificate>
<serviceCertificate findValue="MyServer" storeLocation="LocalMachine"
x509FindType
="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="RemoteSQLHelper.CustomUserPassword, RemoteSQLHelper" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

到此wcf服务已完成.

 4.客户端调用

代码
RSQLHeplerClient client = new RSQLHeplerClient();
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode
=X509CertificateValidationMode.None;
client.ClientCredentials.UserName.UserName
= "admin";
client.ClientCredentials.UserName.Password
= "*******";
object len=client.GetSingle("****");

有些朋友会想到把证书添加到"CURRENT_USER"存储区,调试时会通过,但在IIS会出现找不到证书的问题

注:

 http://support.microsoft.com/kb/901183/zh-cn

原文地址:https://www.cnblogs.com/wudingfeng/p/1656593.html