我正在尝试了解 WCF 及其所有(复杂)安全选项。我在 localhost 上开发了一个带有 wsHttpBinding 的 Wcf Web 服务。我正在创建一个控制台应用程序,我将分发给几个客户端。每个客户都有自己的用户名和密码,我将根据自己的数据库进行验证。为此,我遵循了 codebetter.com 上的以下教程:http: //codebetter.com/petervanooijen/2010/03/22/a-simple-wcf-service-with-username-password-authentication-the-他们不告诉你的事情/
- 我获得了自签名证书,并授予了权限
- 我得到了服务器和客户端的所有设置并在 localhost 到 localhost 上完美运行。
问题一:
我使用 VS2010 添加服务对话框添加了 svc 服务,并将以下标记添加到我的 app.config 中:
<certificate encodedValue="AwA<...>" />
出于学习目的,我更改了几次该值,但没有任何效果。它一直在完美地工作。我使用 Fiddler 来查看加密的通信。
问题 2:使用 SSL 部署在测试服务器上
我已经在配置了 IIS7.5 和 SSL 的测试服务器上部署了托管 WCF 服务的 Web 应用程序。当我尝试客户端应用程序连接到测试服务器时,它抛出了一个通用错误。我发现当我从 https:// 更改为 http:// 时,它起作用了。Fiddler 展示了带有加密值的良好 http 通信。
但我也想使用 HTTPS,以及我的消息级加密。我认为这是不可能的。我得到了一切工作,只需将安全模式设置为“TransportWithMessageCredential”就可以了。但是当我这样做时,我可以删除客户端上的所有证书信息,它仍然有效。因此,我可以得出结论,传输安全(某种)高于消息安全。
所以我得出正确的结论:
- 没有 https 传输安全性?使用证书(服务器上的 pfx,客户端上的证书)
- 有 https 传输安全性吗?不要使用证书,SSL 就足够了。
我希望我说清楚:)。提前谢谢了。
下面是一些(匿名的)配置:
服务器
<bindings>
<wsHttpBinding>
<!--The maximum size, in bytes, for a message that is processed by the binding-->
<binding name="Binding1" maxReceivedMessageSize="4194304">
<readerQuotas maxDepth="32" maxStringContentLength="10485760" maxArrayLength="10485760"
maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ApiWcfCustomBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomUserNameValidator, SupplierAPI"/>
<serviceCertificate findValue="xxxxApiv3" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
* 客户 *
var endPoint = new EndpointAddress(new Uri(apiUrl), EndpointIdentity.CreateDnsIdentity(endpointDnsEntity));
var binding = new WSHttpBinding();
//binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.NegotiateServiceCredential = false;
using (var client = new SupplierServiceClient(binding, endPoint))
{
client.ClientCredentials.UserName.UserName = supplierUID;
client.ClientCredentials.UserName.Password = supplierPassword;
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName,
endpointDnsEntity);
}