背景:在Win 7+IIS7的环境下,开发基于basicHttpBinding ,netTcpBinding的Username认证的WCF服务。
basicHttpBinding, netTcpBinding的认证方式使用UserName时,WCF限制不能传输明文的username/password,wcf限制请使用ssl、x.509加密解密2中途径。
下面是使用UserName的一种绑定配置:
<netTcpBinding>
<binding name="securityconfg">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
basicHttpBinding:
basicHttpBinding 的UserName需要在IIS网址的绑定添加https协议,并指定SSL证书。MSDN的说明:For the basicHttpBinding, this requires setting up an SSL channel.
netTcpBinding:
可以使用https指定的SSL证书,也可以重新创建新的证书:
做个测试程序就没有必要去申请一个X509数字签名证书了,微软提供了一个makecert.exe的命令专门用来生成测试使用的X509证书的,那我们就来建立一个测试用的证书,在cmd下输入以下命令:
makecert.exe -sr LocalMachine -ss My -a sha1 -n CN=MyServer -sky exchange –pe
这个命令的意思就是创建一个测试的X509证书,这个证书放在存储位置为'Localmachine'的'My'这个文件夹下,证书主题名字叫'MyServer',需要更多关于makecert命令的信息请参考MSDN。
对应的配置如下:
<serviceCertificate storeName="My" findValue="MyServer"
x509FindType="FindBySubjectName" storeLocation="LocalMachine"/>
需要注意的2点:
1,需要设置IIS宿主对密钥访问权限,方法如下:
下载FindPrivateKey.exe工具,通过命令查找指定证书
FindPrivateKey My LocalMachine -n "CN= MyServer "
查找到对应的密钥存放位置,然后找到此文件,在文件属性安全添加IIS_IUSRS用户的读权限。
2,由于使用的是测试证书,客户端调用时可能遇到下面的提示:
X.509 certificate CN=MyServer 链生成失败。所使用的证书具有无法验证的信任链。请替换该证书或更改 certificateValidationMode
解决方法:
在客户单的app.config/web.config中添加如下行为(禁用证书验证,正式环境可以不用)并修改配置文件中对应endpoint的behaviorConfiguration="myClientBehavior"。
<behaviors>
<endpointBehaviors>
<behavior name="myClientBehavior">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
关于negotiateServiceCredential 属性说明:
negotiateServiceCredential 默认值为true,此属性指示是否在客户端和服务之间自动协商服务证书。如果此属性为 true,则会进行此类协商。如果此属性为 false,则与服务通信之前必须在客户端指定服务证书。服务端必须始终指定一个证书。例如下面的配置,就需要在客户端指定证书。
<security mode="Message">
<message clientCredentialType="UserName" negotiateServiceCredential ="false"/>
</security>
扩展阅读:
WCF ClearUsernameBinding: Send username without SSL or x.509 certificates