具有传输和消息安全性的WCF安全通信

具有传输和消息安全性的WCF安全通信,wcf,security,certificate,Wcf,Security,Certificate,我试图了解WCF及其所有(复杂的)安全选项。我在本地主机上开发了一个带有wsHttpBinding的Wcf Web服务。我正在创建一个控制台应用程序,将其分发给几个客户端。每个客户端都有自己的用户名和密码,我将根据自己的数据库进行验证。为此,我在codebetter.com上学习了以下教程: 我获得了自签名证书,并授予了权限 我得到了服务器和客户端的所有设置,并在本地主机对本地主机上完美运行 问题1: 我使用VS2010添加服务对话框添加了svc服务,并将以下标记添加到我的app.confi

我试图了解WCF及其所有(复杂的)安全选项。我在本地主机上开发了一个带有wsHttpBinding的Wcf Web服务。我正在创建一个控制台应用程序,将其分发给几个客户端。每个客户端都有自己的用户名和密码,我将根据自己的数据库进行验证。为此,我在codebetter.com上学习了以下教程:

  • 我获得了自签名证书,并授予了权限
  • 我得到了服务器和客户端的所有设置,并在本地主机对本地主机上完美运行
问题1:

我使用VS2010添加服务对话框添加了svc服务,并将以下标记添加到我的app.config中:

<certificate encodedValue="AwA<...>" />

我现在正在尝试做类似的事情(SSL、消息加密、用户名/密码身份验证),我也开始认为这是不可能的,至少如果没有一些我不知道的黑客攻击,这是不可能的。如果我理解正确,当您的客户端计算机通过SSL直接连接到您的服务计算机时,您将拥有一个点对点连接,这意味着它是通过SSL进行安全保护的,并且身份验证(用户名/密码值)是通过WS-Security进行安全保护的

这篇文章中使用的一个有趣的类比是SSL上的网上银行。由于客户端和服务器具有点对点连接,因此您将拥有一个安全通道


这正是我所发现的,所以如果有人认为这是不正确的,请告诉我。

我现在正在尝试做类似的事情(SSL、消息加密、用户名/密码验证),我也开始认为这是不可能的,至少在没有我不知道的黑客攻击的情况下是不可能的。如果我理解正确,当您的客户端计算机通过SSL直接连接到您的服务计算机时,您将拥有一个点对点连接,这意味着它是通过SSL进行安全保护的,并且身份验证(用户名/密码值)是通过WS-Security进行安全保护的

这篇文章中使用的一个有趣的类比是SSL上的网上银行。由于客户端和服务器具有点对点连接,因此您将拥有一个安全通道


这正是我所发现的,因此如果有人认为它不正确,请让我知道。

re:问题1-您在配置中更改了证书值,但仍将数据视为加密的。。。是通过HTTPS吗?@MarkB,谢谢你的评论。不,不是通过HTTPS。当使用Fiddler和HTTPS时,我只看到一个结果,不可读(ssl)。我做的这个测试,我是正常的HTTP,我可以看到一些HTTP请求,体内有加密的数据。更改客户端值时,什么也没做。@MarkB当然,我开始怀疑并再次进行测试。安装程序如下:在VS2012中使用新的控制台应用程序的笔记本电脑(未预装证书)。从测试服务器添加了WCF服务引用(非https)。身份/certificate@encodedValue已添加到app.config。做了几次测试,效果很好。更改encodedValue(替换一些字符)没有任何作用。只有完全删除标识标签后,控制台应用程序才会抛出一个错误。@Tweek根据我的经验,它在更改第6个字符后生效。re:question 1-您在配置中更改了该证书值,但仍然将数据视为加密的。。。是通过HTTPS吗?@MarkB,谢谢你的评论。不,不是通过HTTPS。当使用Fiddler和HTTPS时,我只看到一个结果,不可读(ssl)。我做的这个测试,我是正常的HTTP,我可以看到一些HTTP请求,体内有加密的数据。更改客户端值时,什么也没做。@MarkB当然,我开始怀疑并再次进行测试。安装程序如下:在VS2012中使用新的控制台应用程序的笔记本电脑(未预装证书)。从测试服务器添加了WCF服务引用(非https)。身份/certificate@encodedValue已添加到app.config。做了几次测试,效果很好。更改encodedValue(替换一些字符)没有任何作用。只有完全删除标识标签后,控制台应用程序才会抛出一个错误。@Tweek根据我的经验,更改第6个字符后,它才生效。
<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);
 }