Wcf Basic аутентификация

Возникли проблемы при использовании базовой аутентификации с простым тестовым сервисом Wcf. Я получаю исключение:

Запрашиваемая служба http://qld-tgower/test/Service.svc не может быть активирована. См.> Журналы диагностической трассировки сервера для получения дополнительной информации.

И в журнале трассировки это показывает:

Схемы аутентификации, настроенные на хосте ("Basic"), не допускают тех схем, которые настроены на привязке "BasicHttpBinding" ("Anonymous"). Убедитесь, что для SecurityMode установлено значение Transport или TransportCredentialOnly. Кроме того, это может быть решено путем изменения схем аутентификации для этого приложения с помощью инструмента управления IIS через свойство ServiceHost.Authentication.AuthenticationSchemes в файле конфигурации приложения в элементе путем обновления свойства ClientCredentialType в привязке, или путем настройки свойства AuthenticationScheme в HttpTransportBindingElement.

Но что я не понимаю, когда я использую неправильное имя пользователя и пароль, который говорит, что он использует обычную аутентификацию?

HTTP-запрос не авторизован с помощью схемы аутентификации клиента "Basic". Заголовок аутентификации, полученный от сервера, был 'Basic realm="qld-tgower"'.

Это мои данные web.config

<system.serviceModel>
<services>
  <service name="WcfService"
      behaviorConfiguration="Behavior">
    <endpoint address="http://QLD-TGOWER/test/Service.svc"
              binding="basicHttpBinding"
              bindingConfiguration="httpBinding"
              contract="IService" />
  </service>
</services>
<diagnostics>
  <endToEndTracing activityTracing="false" messageFlowTracing="true" propagateActivity="true"></endToEndTracing>
</diagnostics>
<bindings>
  <basicHttpBinding>
    <binding name="httpBinding">
      <security mode="TransportCredentialOnly">
        <transport  clientCredentialType="Basic" proxyCredentialType="Basic">
        </transport>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>

и это мой App.config

<system.serviceModel>
    <diagnostics>
      <endToEndTracing activityTracing="true" />
      <messageLogging logMessagesAtTransportLevel="true" />
    </diagnostics>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService" >
          <security mode="TransportCredentialOnly">

            <transport clientCredentialType="Basic" proxyCredentialType="Basic"></transport>
            <message clientCredentialType="UserName" />
          </security>

        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://QLD-TGOWER/test/Service.svc" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
        name="BasicHttpBinding_IService" />
    </client>
</system.serviceModel>

мое тестовое приложение

private static void Main(string[] args)
{
    var proxy = new ServiceClient("BasicHttpBinding_IService");
    var clientCredentials = proxy.ClientCredentials;
    clientCredentials.UserName.UserName = "username";
    clientCredentials.UserName.Password = "password";
    var res = proxy.GetData(1);
    Console.WriteLine(res);
    Console.WriteLine("Done");
    Console.ReadKey(true);
}

И мой сервис

public class Service : IService
{

   public string GetData(int value)
   {
       return string.Format("You entered: {0}", value);
   }
}

Есть ли что-то, что мне здесь не хватает?

4 ответа

Решение

Измените имя и контракт службы, чтобы включить пространство имен.

Кроме того, удалите адрес конечной точки (установите его в "") и не включайте proxyCredentialType в транспортный тег.

Конечный результат web.config должен выглядеть примерно так

  <system.serviceModel>

    <services>
      <service name="MyNameSpace.MyService" behaviorConfiguration="asdf">
        <endpoint address="" binding="basicHttpBinding" 
            bindingConfiguration="httpBinding" contract="MyNameSpace.IMyService" />
      </service>
    </services>

    <diagnostics>
      <endToEndTracing activityTracing="true" messageFlowTracing="true" 
          propagateActivity="true">
      </endToEndTracing>
    </diagnostics>

    <bindings>
      <basicHttpBinding>
        <binding name="httpBinding">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="asdf">
          <!-- To avoid disclosing metadata information, set the value below to 
               false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, 
               set the value below to true.  Set to false before deployment to avoid 
               disclosing exception information -->
          <serviceDebug  includeExceptionDetailInFaults="true" />

        </behavior>
      </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment multipleSiteBindingsEnabled="false"/>

  </system.serviceModel>

Попробуйте как для клиента, так и для сервера конфигурации

<basicHttpBinding>
    <binding name="BasicHttpBinding_IService">
        <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic" />
        </security>
    </binding>
</basicHttpBinding>

Установить / включить базовую аутентификацию

Вам также может понадобиться установить и применить базовую аутентификацию в IIS.

Перейдите в раздел "Программы и компоненты" / "Включить / выключить функции Windows". Включите "базовую аутентификацию" где-нибудь под IIS и безопасностью.

Я закрыл и открыл консоль IIS и смог включить ее в настройках аутентификации.

Это, конечно, если для тестирования разработки, и он предупреждает вас об отсутствии сертификата SSL.

Вот что решило проблему для меня:

<bindings>
  <basicHttpBinding>
    <binding>
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>

Для справки: https://msdn.microsoft.com/en-gb/library/ff648505.aspx

Вы не можете использовать аутентификацию по имени пользователя через незащищенное соединение

Вы можете защитить сообщение, используя безопасный транспорт (например, SSL) или шифрование сообщений (используя сертификаты)

Я использовал ClearUsernameBinding в прошлом с большим успехом, но я не рекомендую его в производстве. Я использовал его так, чтобы я мог сохранить все свои коды аутентификации одинаковыми, не требуя SSL в средах разработки и тестирования, но работая с SSL, изменяя только конфигурацию.

Примечание: эта привязка не идеальна, и мне пришлось немного ее изменить, чтобы включить определенные изменения конфигурации.

Другие вопросы по тегам