WCF IIS 用户名消息安全 可能碰到的问题
在IIS 托管WCF其实很简单
在要提供服务的文件目录下新建一个*.SVC,内容类似
<%@ ServiceHost Language="C#" Debug="true" Service="Baice.eTerm.SearchService.Service.SearchTicket" %>
Baice.eTerm.SearchService.Service.SearchTicket(类名)
建立一个web.config,适当的配置,跟WCF有关的节点可以类似如下。
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="searchTicketServieBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceCredentials>
<serviceCertificate findValue="localhost"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="searchTicketServieBehavior"
name="Baice.eTerm.SearchService.Service.SearchTicket">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="MessageAndUserName"
name="SecuredByTransportEndpoint"
contract="Baice.eTerm.SearchService.Contract.ITicketSearch" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="MessageAndUserName">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client />
</system.serviceModel>
建立一个bin目录,把需要的dll文件移入。
================================================
接下来就是配置的事情,
用类似的命令
创建服务器证书
echo ************
echo Server cert setup starting
echo %SERVER_NAME%
echo ************
echo making server cert
echo ************
makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN=myService -sky exchange -pe
将以上内容拷贝到文本文件,重命名为setup.bat,然后运行,
将会创建证书。查看该证书用如下方法
开始 > 运行 > MMC,打开一个空的MMC控制台。
l 在控制台菜单,文件 > 添加/删除管理单元 > 添加按钮 > 选”证书” > 添加 > 选”我的用户账户” > 关闭 > 确定
l 在控制台菜单,文件 > 添加/删除管理单元 > 添加按钮 > 选”证书” > 添加 > 选”计算机账户” > 关闭 > 确定
就可以看到您的证书了,我的证书过期日期是2040年。
接着要给IIS一个访问证书的权限,
echo ************
echo setting privileges on server certificates
echo ************
for /F "delims=" %%i in ('"%ProgramFiles%\ServiceModelSampleTools\FindPrivateKey.exe" My LocalMachine -n CN^=%SERVER_NAME% -a') do set PRIVATE_KEY_FILE=%%i
set WP_ACCOUNT=NT AUTHORITY\NETWORK SERVICE
(ver | findstr /C:"5.1") && set WP_ACCOUNT=%COMPUTERNAME%\ASPNET
echo Y|cacls.exe "%PRIVATE_KEY_FILE%" /E /G "%WP_ACCOUNT%":R
iisreset
如果提示类似的错误: 该进程必须具有访问私钥的权限,必须具有能够进行密钥交换的私钥
您可以进入
Win Xp /2003 在 C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA
Win Vista /2008 在C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\ (参考上面那个也可以, 开头的换成 C:\Users\)
给IIS运行用户设定适当的权限。
'X.509 certificate CN=MyServerCert 链生成失败。所使用的证书具有无法验证的信任链。请替换该证书或更改 certificateValidationMode。已处理证书链,但是在不受信任提供程序信任的根证书中终止',WCF无法验证测试证书的信任链,
客户端引用:System.IdentityModel
新建类似如下的类
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Cryptography.X509Certificates;
namespace ClientWeb.CustomX509Validator
{
/// <summary>
/// Implements the validator for X509 certificates.
/// </summary>
public class MyX509Validator: X509CertificateValidator
{
/// <summary>
/// Validates a certificate.
/// </summary>
/// <param name="certificate">The certificate the validate.</param>
public override void Validate(X509Certificate2 certificate)
{
// validate argument
if (certificate == null)
throw new ArgumentNullException("X509认证证书为空!");
}
}
修改客户端配置:
<behaviors>
<endpointBehaviors>
<behavior name="myClientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="Custom" customCertificateValidatorType="ClientWeb.CustomX509Validator.MyX509Validator,ClientWeb" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
并在'endpoint'节中指定behaviorConfiguration="myClientBehavior"。
最后在IIS转WINFORM委托的时候又碰到 问题,类似错误是:基址等,由于前面的配置可能有些省略了,经过认真比照才发现需要加如下的节点在服务端。
<host>
<baseAddresses>
<add baseAddress="http://localhost:9191/TicketSearch"/>
</baseAddresses>
</host>
现在WCF能跑了。该文章主要是记录整个学习过程碰到的各种错误,如果您是系统的学习也许碰不到这样的错误,见笑了!