【问题标题】:the most efficient way to secure WCF NetHttpBinding保护 WCF NetHttpBinding 的最有效方法
【发布时间】:2015-10-28 16:44:27
【问题描述】:

我将实现一个在NetHttpBinding 下工作的网络服务,以支持双工连接。但问题是我不知道如何保护它。我试过用CostumUserNamePasswordValidationMode,这是我的web.config

<behaviors>
      <serviceBehaviors>
        <behavior name="Behavior1">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="MyWebSite"
                  storeLocation="LocalMachine"
                  storeName="My"
                  x509FindType="FindBySubjectName" />
            <userNameAuthentication userNamePasswordValidationMode="Custom"
             customUserNamePasswordValidatorType="WcfWSChat.UserNamePassValidator, WcfWSChat" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netHttpBinding>
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netHttpBinding>
    </bindings>
    <protocolMapping>
      <add scheme="http" binding="netHttpBinding"/>
    </protocolMapping>
    <services>
      <service name="WcfWSChat.WSChatService" 
               behaviorConfiguration="Behavior1" >
        <endpoint address="" 
                  binding="netHttpBinding"
                  bindingConfiguration="Binding1"
                  contract="WcfWSChat.IWSChatService" />
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
    </services>

我认为问题是&lt;security mode="Message"&gt;,每当我运行项目时,无论是在 IIS Express 还是 IIS 8.0 上,我都会收到此错误:

找不到与具有绑定 NetHttpBinding 的端点的方案 https 匹配的基地址。注册的基地址方案是 [http]。

如果我将mode 属性更改为None,我将不会再看到错误但验证不起作用!

我该如何解决这个问题?

【问题讨论】:

  • 这个问题有什么进展吗?

标签: c# wcf iis websocket


【解决方案1】:

似乎这可能与您注册为服务凭据的证书有关。

我会尝试从serviceBehaviours 中删除serviceCertificate

如果您想通过该证书强制执行 SSL,那么我会将绑定部分中的安全模式更新为 TransportWithMessageCredential,并将您的协议映射方案更改为 https

【讨论】:

  • 我想使用自签名证书而不是 SSL
  • 我不明白您的意思...您是否打算将证书用作凭据但不使用它加密流量?您可能还需要考虑向证书添加正确的权限,以便您的应用程序可以访问证书的私钥。
【解决方案2】:

我认为您几乎接近解决方案。我试图复制你的问题,这就是我的想法。

  1. 在您的 ServiceMetadata 中添加 httpsGetEnabled 并将其设置为 true。元数据交换将在 HTTPS 中进行:

&lt;serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" /&gt;

  1. 将 mexHttpBinding 更改为 mexHttpsBinding :

<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>

  1. 在您的绑定中添加:
<netHttpBinding>
   <binding name="netHttpBinding">
       <security mode="TransportWithMessageCredential">
           <message clientCredentialType="UserName"/>
       </security>
   </binding>
</netHttpBinding>
  1. 由于netHttpBinding默认使用http,我们需要一些映射。
<protocolMapping>
    <add scheme="https" binding="netHttpBinding"/>
</protocolMapping>
  1. 出于某种原因,即使我将 protocolMapping 更改为对 netHttpBinding 使用 HTTPS,我仍然收到一条错误消息,提示 “找不到与绑定 NetHttpBinding 的端点的方案 https 匹配的基地址。已注册基地址方案是 [http]。”

所以我所做的是,我在我的服务下添加了基础地址,如下所示:

<host>
    <baseAddresses>
       <add baseAddress="https://localhost/Services/"/>
    </baseAddresses>
</host>

如果您没有看到上面突出显示的任何错误消息,您可以跳过第五步。我只是把它放在这里以防万一。

注意:我将证书安装在 Personal 下的证书存储中,并将 CA 安装在受信任的根证书中。此示例仅在同一台机器下工作,因为我的证书名称只是 localhost。顺便说一句,我在这里使用了 .Net framework 4.5。

以下是我的完整配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1" behaviorConfiguration="ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost/Services/"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="netHttpBinding"  bindingConfiguration="netHttpBinding" contract="WcfServiceLibrary1.IService1" name="WcfServiceLibrary1.IService1"/>
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" listenUriMode="Explicit" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors >
        <behavior name="ServiceBehavior">
          <serviceCredentials>
            <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
            **<!-- Retain your custom username password validator here -->**
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netHttpBinding>
        <binding name="netHttpBinding">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netHttpBinding>
    </bindings>
    <protocolMapping>
      <add scheme="https" binding="netHttpBinding"/>
    </protocolMapping>
  </system.serviceModel>
</configuration>

【讨论】:

  • 伙计们,我认为您应该使用netHttpsBinding 而不是进行这些映射。只是一个想法。
  • 另外,您必须设置baseAddress 来解决“找不到...”问题的原因是应用程序没有向 HTTP.sys 注册地址(因为你做了映射,但实际上没有任何东西绑定在 https 地址上)。使用正确的绑定应该可以解决这个问题。
  • 感谢您的信息,我已经想到了,但我克制自己改变他的绑定,因为这就是他想要的方式。尽管如此,netHttpBinding 对于这个问题仍然有效:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多