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">
<!-- To receive fault exceptions as detailed error messages, set the following value to true. Set to false before deployment to avoid leaking exception information -->
<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会出现找不到证书的问题