Подтвердить что ты не робот

Самый эффективный способ защиты WCF NetHttpBinding

Я собираюсь внедрить веб-службу, которая работает под 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>

Я думаю, что проблема <security mode="Message">, всякий раз, когда я запускаю проект, будь то в IIS Express или IIS 8.0, я получаю эту ошибку:

Не удалось найти базовый адрес, соответствующий схеме https для конечной точки с привязкой NetHttpBinding. Зарегистрированные базовые адресные схемы: [http].

Если я изменю свойство mode на None, я больше не буду видеть ошибку, но проверка не работает!

Как я могу решить эту проблему?

4b9b3361

Ответ 1

Я думаю, вы почти близки к решению. Я попытался воспроизвести вашу проблему, и вот как я подошел.

  • Добавьте и установите для httpsGetEnabled значение true в вашем ServiceMetadata. Обмен метаданных произойдет в HTTPS:

<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />

  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. По какой-то причине даже я изменяю протоколMapping для использования HTTPS для netHttpBinding, я все еще получаю сообщение об ошибке "Не удалось найти базовый адрес, соответствующий схеме https для конечной точки с привязкой NetHttpBinding. HTTP]." .

Итак, что я сделал, я добавил адрес под моей службой следующим образом:

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

Вы можете избежать пятого шага, если вы не заметили сообщение об ошибке, выделенное выше. Я просто поставлю его здесь на случай.

Примечание. Я установил свой сертификат в хранилище сертификатов в Личном кабинете и в доверенном корневом сертификате. Этот пример работает только на одном компьютере, так как имя моего сертификата - только 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>

Ответ 2

Похоже, что это может иметь какое-то отношение к сертификату, который вы зарегистрировали в качестве учетных данных службы.

Я попробую удалить serviceCertificate из serviceBehaviours.

Если вы хотите использовать SSL через этот сертификат, я бы обновил ваш режим безопасности в разделе привязки до TransportWithMessageCredential и изменил схему сопоставления протокола на https.