【发布时间】:2012-07-15 07:35:40
【问题描述】:
我正在尝试了解 WCF 及其所有(复杂的)安全选项。我在 localhost 上开发了一个带有 wsHttpBinding 的 Wcf Web 服务。我正在创建一个控制台应用程序,我将分发给几个客户端。每个客户都有自己的用户名和密码,我将根据自己的数据库进行验证。为此,我遵循了 codebetter.com 上的以下教程:http://codebetter.com/petervanooijen/2010/03/22/a-simple-wcf-service-with-username-password-authentication-the-things-they-don-t-tell-you/
- 我获得了自签名证书,并授予了权限
- 我已经设置好服务器和客户端,并在 localhost 到 localhost 上完美运行。
问题 1:
我使用 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);
}
【问题讨论】:
-
re:问题 1 - 您在配置中更改了证书值,但仍然看到数据是加密的……是通过 HTTPS 传输的吗?
-
@MarkB,感谢您的评论。不,它不是通过 HTTPS。使用 Fiddler 和 HTTPS 时,我只看到一个结果,不可读(ssl)。我做的这个测试,我是普通的 HTTP,我可以看到一些 http-request,其中包含加密数据。更改客户端值,没有做任何事情。
-
@MarkB Offcourse 我开始怀疑并再次进行了测试。设置如下:笔记本电脑(没有预装证书)在 VS2012 中有一个新的控制台应用程序。添加了来自测试服务器的 WCF 服务参考(非 https)。 Identity/certificate@encodedValue 被添加到 app.config。做了一些测试,工作完美。更改编码值(替换一些字符)没有做任何事情。只有完全删除 Identity 标签才会导致控制台应用程序抛出错误。
-
@Tweek 根据我的经验,它在更改第 6 个字符后生效。
标签: wcf security certificate